源码阅读苦练基本功golang内置函数分析(代码片段)

在路上的德尔菲 在路上的德尔菲     2022-12-11     362

关键词:

Golang package builtin 中内置函数我分为两部分介绍,第一部分为基础类型,第二部分为包含函数、接口,较复杂一些

第一部分

// bool is the set of boolean values, true and false.
type bool bool

// true and false are the two untyped boolean values.
const (
	true  = 0 == 0 // Untyped bool.
	false = 0 != 0 // Untyped bool.
)

// uint8 is the set of all unsigned 8-bit integers.
// Range: 0 through 255.
type uint8 uint8

// uint16 is the set of all unsigned 16-bit integers.
// Range: 0 through 65535.
type uint16 uint16

// uint32 is the set of all unsigned 32-bit integers.
// Range: 0 through 4294967295.
type uint32 uint32

// uint64 is the set of all unsigned 64-bit integers.
// Range: 0 through 18446744073709551615.
type uint64 uint64

// int8 is the set of all signed 8-bit integers.
// Range: -128 through 127.
type int8 int8

// int16 is the set of all signed 16-bit integers.
// Range: -32768 through 32767.
type int16 int16

// int32 is the set of all signed 32-bit integers.
// Range: -2147483648 through 2147483647.
type int32 int32

// int64 is the set of all signed 64-bit integers.
// Range: -9223372036854775808 through 9223372036854775807.
type int64 int64

// float32 is the set of all IEEE-754 32-bit floating-point numbers.
type float32 float32

// float64 is the set of all IEEE-754 64-bit floating-point numbers.
type float64 float64

// complex64 is the set of all complex numbers with float32 real and
// imaginary parts.
type complex64 complex64

// complex128 is the set of all complex numbers with float64 real and
// imaginary parts.
type complex128 complex128

// string is the set of all strings of 8-bit bytes, conventionally but not
// necessarily representing UTF-8-encoded text. A string may be empty, but
// not nil. Values of string type are immutable.
type string string

// int is a signed integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, int32.
type int int

// uint is an unsigned integer type that is at least 32 bits in size. It is a
// distinct type, however, and not an alias for, say, uint32.
type uint uint

// uintptr is an integer type that is large enough to hold the bit pattern of
// any pointer.
type uintptr uintptr

// byte is an alias for uint8 and is equivalent to uint8 in all ways. It is
// used, by convention, to distinguish byte values from 8-bit unsigned
// integer values.
type byte = uint8

// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
type rune = int32

主要注意几个点:

  • type int int 大小至少32位也就是至少4字节,为什么说是至少呢?因为int类型所占字节数跟操作系统有关,如果是32位就是4个字节,如果是64位就是8个字节,type int inttype int32 int32不同,int32永远是32位,int64永远是64位。
  • type string string string可能是空,但不能为nil,这一点和Java不同,Java中String可以为null。string是不可变的,这一点和Java相同。
  • type uintptr uintptr 是一个integer类型,空间足够大可存储任何指针。
  • byteuint8类型是相同的,可以说是uint8的别称,byte更简单一些。
  • runeint32类型是相同的,rune更简单一些。

第二部分

any

// any is an alias for interface and is equivalent to interface in all ways.
type any = interface

anyinterface 是相同的,不要以为是泛型关键词,为了少写一些字母所以会用any,下面举了一个例子

	func convert(t any)
		switch t.(type)
			case int:
				//
			case string:
				//
			case bool:
				//
		
	
	
	func main() 
		f(2)
		f(true)
		f("煎鱼好!")
	

comparable

// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface comparable 

comparable是由所有可比较类型(包括booleans, numbers, strings, pointers, channels,interface, arrays中元素为可比较类型,
以及structs 中所有属性都是可比较类型)实现的接口。只能用于类型参数约束,不用于变量类型比较,举个🌰:

	func SumNumbers[K comparable, V int](m map[K]V) V 
	    var s V
	    for _, v := range m 
	        s += v
	    
	    return s
	

	//入参
    ints := map[string]int
        "first":  34,
        "second": 12,
    
    //调用
	SumIntsOrFloats[string, int](ints)

  1. T is not an interface type and T supports the operations == and !=; or
  2. T is an interface type and each type in T’s type set implements comparable.

下面大多数都是上面1类型,其中interface属于上面2类型。支持的类型以下列举出来:

  • Boolean values are comparable. Two boolean values are equal if they are either both true or both false.
  • Integer values are comparable and ordered, in the usual way.
  • Floating-point values are comparable and ordered, as defined by the IEEE-754 standard.
  • Complex values are comparable. Two complex values u and v are equal if both real(u) == real(v) and imag(u) == imag(v).
  • String values are comparable and ordered, lexically byte-wise.
  • Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
  • Channel values are comparable. Two channel values are equal if they were created by the same call to make or if both have value nil.
  • Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.for example interface ~int | ~string
  • A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T. They are equal if t’s dynamic type is identical to X and t’s dynamic value is equal to x.
  • Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
  • Array values are comparable if values of the array element type are comparable. Two array values are equal if their corresponding elements are equal.

Java中Comparable<T>接口是用于比较排序的,Golang中comparable是用于类型限定,功能不同,需要注意。


public interface Comparable<T> 
    public int compareTo(T o);



iota

// iota is a predeclared identifier representing the untyped integer ordinal
// number of the current const specification in a (usually parenthesized)
// const declaration. It is zero-indexed.
const iota = 0 // Untyped int.
  • iota在关键字const出现时重置为0
  • const中每新增一行常量声明将使iota计数一次,下面举了三个例子
const (
		n1 = iota //0
		n2        //1
		n3        //2
		n4        //3
	)
const (
		n1 = iota //0
		n2        //1
		_         //有误
		n4        //2
	)	
const (
		a,b = iota,iota + 1 //0,1
		c,d                 //1,2
		e,f                 //2,3
	)

nil

// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type 
  • nil 只能为 pointer, channel, func, interface, map, or slice 类型,不能为基本数据类型

Type

// Type/Type1 is here for the purposes of documentation only. It is a stand-in
// for any Go type, but represents the same type for any given function
// invocation.
type Type int
type Type1 int

// IntegerType is here for the purposes of documentation only. It is a stand-in
// for any integer type: int, uint, int8 etc.
type IntegerType int

// FloatType is here for the purposes of documentation only. It is a stand-in
// for either float type: float32 or float64.
type FloatType float32

// ComplexType is here for the purposes of documentation only. It is a
// stand-in for either complex type: complex64 or complex128.
type ComplexType complex64

Go 为预定义标识提供的文档说明,在IDE中使用,并非真正实现,不用特别关注。


append


// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//	slice = append(slice, elem1, elem2)
//	slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//	slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type
  • append 函数只能用于slice数据结构上,将元素添加到切片末尾并返回结果
  • 调用append函数只能用原来的切片变量接收返回值
  • append追加元素,如果底层数组有空间的话,将新元素放在切片剩余空间中,如果底层数据没有空间,会新创建一个新的底层数组,将原来切片中元素拷贝到新切片中,返回一个新的切片,切片地址信息也会发生改变。
  • append扩容原理,在一定大小内容量内cap会double增加,在大于阈值后cap按1.25倍增加,目的是节约提前分配空间。
/*例子1*/
	var boys []string
	//len(boys) = 4, cap(boys) = 4
	boys = append(boys, "panda", "jack", "bingo", "hans")
	//len(boys) = 5, cap(boys) = 8
	boys = append(boys, "baobao")

/*例子2*/
	girls := []string"happy","doudou","marni"
	girls2 := []string"jiu"
	girls = append(girls, girl2...)


/*例子3*/
	intSlice := []int1,2,3,4,5,6,7,8,9
	//4,5,6,7,8,9
	intSlice2 := append(intSlice[:0],intSlice[3:]...)
	//1,2,3,7,8,9
	intSlice3 := append(intSlice[:3],intSlice[:6]...)
	//1,2,3,4,5,6
	intSlice4 := append(intSlice[:0],intSlice[:6]...)

/*例子4反面例子*/	
	slice1 : = []string"hello"
	name := "world"
	slice2 := []string"goodbye"
	//编译错误,必须有接收值
	append(slice1, name)
	//编译错误,接收slice2不是原slice1
	slice2 = append(slice1, name)

copy

// The copy built-in function copies elements from a source slice into a
// destination slice. (As a special case, it also will copy bytes from a
// string to a slice of bytes.) The source and destination may overlap. Copy
// returns the number of elements copied, which will be the minimum of
// len(src) and len(dst).
func copy(dst, src []Type) int
  • copy从一个切片拷贝到另一个目的切片上,原切片和目的切片可能交叉,
  • copy返回复制的元素的个数,为len(src)len(dst)中的最小值
  • 注意copy函数第一个参数是目的切片,第二个参数是原切片
/*例子*/
	slice1 := []int1,2,3,4,5
	slice2 := []int6,7,8
	//slice1 6,7,8,4,5 ,返回3
	copy(slice1, slice2)
	//slice2 1,2,3 ,返回3
	copy(slice2, slice1)
	//slice2 2,3,4 ,返回3
	copy(slice2, slice1[1:4])

有点类似Java中Arrays.copy()


delete

// The delete built-in function deletes the element with the specified key
// (m[key]) from the map. If m is nil or there is no such element, delete
// is a no-op.
func delete(m map[Type]Type1, key Type)
  • delete函数用于删除map的key-value,类似于Java Map.remove(Key)操作
  • delete函数第一个参数为map,第二个参数为key值,注意如果map为空或者map中没有该key,相当于没有做任何操作
  • 没有返回值,并不知道是否有删除操作或者没有删除操作,需要通过map的大小来判断吗?

len / cap

// The len built-in function returns the length of v, according to its type:
//	Array: the number of elements in v.
//	Pointer to array: the number of elements in *v (even if v is nil).
//	Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
//	String: the number of bytes in v.
//	Channel: the number of elements queued (unread) in the channel buffer;
//	         if v is nil, len(v) is zero.
// For some arguments, such as a string literal or a simple array expression, the
// result can be a constant. See the Go language specification's "Length and
// capacity" section for details.
func len(v Type) int

// The cap built-in function returns the capacity of v, according to its type:
//	Array: the number of elements in v (same as len(v)).
//	Pointer to array: the number of elements in *v (same as len(v)).
//	Slice: the maximum length the slice can reach when resliced;
//	if v is nil, cap(v) is zero.
//	Channel: the channel buffer capacity, in units of elements;
//	if v is nil, cap(v) is zero.
// For some arguments, such as a simple array expression, the result can be a
// constant. See the Go language specification's "Length and capacity" section for
// details.
func cap(v Type) int
  • len函数可用于array、指向Array的指针、slice、map、string、channel
  • cap函数可用于array、指向Array的指针、slice、channel,相比len少了string和map
/*例子1*/
	array := [5]int1,2,3
	//len(array)为5,cap(array)为5
	
/*例子2*/
	arrayP := &[5]int1,2,3
	//len(arrayP)为5,cap(arrayP)为5

/*例子3*/
	map1 := map[string]int"panda":4,"marni":3
	//len(map1)为2

    //slice省略在上面append函数章节有解释
/*例子4*/
	str := "hello world"
	//len(str)为11

/*例子5*/
	intChan = make(chan int, 3)
	intChan<-10
	intChan<-20
	//len(intChan)为2,cap(intChan)为3

make

// The make built-in function allocates and initializes an object of type
// slice, map, or chan (only). Like new, the first argument is a type, not a
// value. Unlike new, make's return type is the same as the type of its
// argument, not a pointer to it. The specification of the result depends on
// the type:
//	Slice: The size specifies the length. The capacity of the slice is
//	equal to its length. A second integer argument may be provided to
//	specify a different capacity; it must be no smaller than the
//	length. For example, make([]int, 0, 10) allocates an underlying array
//	of size 10 and returns a slice of length 0 and capacity 10 that is
//	backed by this underlying array.
//	Map: An empty map is allocated with enough space to hold the
//	specified number of elements. The size may be omitted, in which case
//	a small starting size is allocated.
//	Channel: The channel's buffer is initialized with the specified
//	buffer capacity. If zero, or the size is omitted, the channel is
//	unbuffered.
func make(t Type, size ...IntegerType) Type
  • make函数用于分配内存空间,初始化对象,但是只能用于slice、map、chan类型
  • make第一个参数是类型,不是值,和new函数不同的是返回的是这个类型,而不是指向这个类型的指针,下面分别讲解一下三种类型的
/*例子1*/
	//len为0,cap为10
	slice1 := make([]int, 0, 10)
	//len为10,cap为10
	slice2 := make([]int,10)
	
/*例子2*/
	//map无需指定容量大小,初始化一个空map
	map1 := make(map[string]int)
/*例子3*/
	//通道缓存设置为10
	channel1 := make(chan int, 10)

	//如果为零或忽略大小(不传入第二个参数),则 channel 为无缓冲的
	channel2 := make(chan int, 0)
	channel3 := make(chan int)

new

// The new built-in function allocates memory. The first argument is a type,
// not a value, and the value returned is a pointer to a newly
// allocated zero value of that type.
func new(Type) *Type

new函数是分配内存,输入的参数是类型不是值,返回值是这种类型零值的指针,下面举几个🌰

/*例子1*/
	num5 := new(int)
	fmt.Printf("num5的类型=%T, num5的值=%v, num5的地址=%v\\n", num5, num5, &num5)
	//num5的类型=*int, num5的值=0xc00018e0d0, num5的地址=0xc000186008

/*例子2*/
	new(pb.ArithService)
	//ArithService结构体
	type ArithService struct

/*例子3*/
	new(Call)
	//Call结构体
	type Call struct 
		ServiceMethod string     // The name of the service and method to call.
		Args          any        // The argument to the function (*struct).
		Reply         any        // The reply from the function (*struct).
		Error         error      // After completion, the error status.
		Done          chan *Call // Receives *Call when Go is complete.


complex / real / imag

// The complex built-in function constructs a complex value from two
// floating-point values. The real and imaginary parts must be of the same
// size, either float32 or float64 (or assignable to them), and the return
// value will be the corresponding complex type (complex64 for float32,
// complex128 for float64).
func complex(r, i FloatType) ComplexType

// The real built-in function returns the real part of the complex number c.
// The return value will be floating point type corresponding to the type of c.
func real(c ComplexType) FloatType

// The imag built-in function returns the imaginary part of the complex
// number c. The return value will be floating point type corresponding to
// the type of c.
func imag(c ComplexType) FloatType

复数一般不会用到,不做过多解释。


close

// The close built-in function closes a channel, which must be either
// bidirectional or send-only. It should be executed only by the sender,
// never the receiver, and has the effect of shutting down the channel after
// the last sent value is received. After the last value has been received
// from a closed channel c, any receive from c will succeed without
// blocking, returning the zero value for the channel element. The form
//	x, ok := <-c
// will also set ok to false for a closed channel.
func close(c chan<- Type)
  • close函数用于chan,chan必须为双向通道或者是单向输入的(send-only)通道,close作用是不允许再向通道中添加元素,从通道中取出元素时不受影响的。
  • 当从关闭的通道取出最后一个元素,再从通道取到的将是零值。
  • x, ok := <-c 对于close来说返回ok为false。

panic

// The panic built-in function stops normal execution of the current
// goroutine. When a function F calls panic, normal execution of F stops
// immediately. Any functions whose execution was deferred by F are run in
// the usual way, and then F returns to its caller. To the caller G, the
// invocation of F then behaves like a call to panic, terminating G's
// execution and running any deferred functions. This continues until all
// functions in the executing goroutine have stopped, in reverse order. At
// that point, the program is terminated with a non-zero exit code. This
// termination sequence is called panicking and can be controlled by the
// built-in function recover.
func panic(v any)
  • panic发生后程序会中断执行,按调用堆栈顺序层层不断向上抛,最后返回一个非0退出码,一般会返回2错误码。
  • panic是底层抽象的错误,空指针、越界等异常具体异常,一般在业务代码里不要直接使用panic
  • 使用panic的场景,举个例子当项目中特别依赖一些组件时,比如一些web项目中经常会在进程启动之前初始化一些mysql,mq句柄。这些实例对业务来说是非常重要的,所以当这些实例初始化失败时我们可以直接让当前程序panic(手动panic),然后及时发现问题并解决。
  • panic函数参数可以是任何类型,下面recover函数是用来处理控制panic的。

recover

// The recover built-in function allows a program to manage behavior of a
// panicking goroutine. Executing a call to recover inside a deferred
// function (but not any function called by it) stops the panicking sequence
// by restoring normal execution and retrieves the error value passed to the
// call of panic. If recover is called outside the deferred function it will
// not stop a panicking sequence. In this case, or when the goroutine is not
// panicking, or if the argument supplied to panic was nil, recover returns
// nil. Thus the return value from recover reports whether the goroutine is
// panicking.
func recover() any
  • recover用于处理控制paniking行为,捕捉panic,恢复程序正常执行,recover返回值为panic发生时的记录,包括panic 设置的入参和函数调用的堆栈跟踪信息。
  • 如果recover放在defer函数以外,recover返回为nil,将不起控制panic的作用,下面反例1展示。
  • 注意将defer语句写在函数的最前面,放在panic后面将不起作用。
/*正面例子*/
	defer func() 
		err := recover()
		if err != nil 
			fmt.Println("err is", err)
		
	()
	panic(errors.New("something wrong"))
	
/*演示几种recover错误用法*/
	//反例1,recover错误用法,此次没有panic发生,recover捕捉不到任何东西,返回nil
	fmt.Printf("no panic: %v\\n", recover())

	//反例2,引发panic,此时程序终止,不会走到下面p := recover()
	panic(errors.New("something wrong"))
	//不会走到此unreachale code
	p := recover()
	fmt.Printf("panic: %s\\n", p)

print / println

// The print built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Print is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func print(args ...Type)

// The println built-in function formats its arguments in an
// implementation-specific way and writes the result to standard error.
// Spaces are always added between arguments and a newline is appended.
// Println is useful for bootstrapping and debugging; it is not guaranteed
// to stay in the language.
func println(args ...Type)
  • print()println() 标准错误打印
  • print()println() 不能打印数组、结构体具体值会打印引用地址值

除非调试启动时和debug时打印日志,其他情况不建议在代码里使用


error

// The error built-in interface type is the conventional interface for
// representing an error condition, with the nil value representing no error.
type error interface 
	Error() string

  • 实现error接口的Error()方法,说明就是一个error类型,如果返回结果为nil说明没有异常。
	//自定义异常结构体
	type ErrInvalidParam struct 
	    ParamName  string
	    ParamValue string
	
	
	func (e *ErrInvalidParam) Error() string 
	    return fmt.Sprintf("invalid param: %+v, value: %+v", e.ParamName, e.ParamValue)
	

	//断言机制,对ErrInvalidParam类型处理
	e, ok := err.(*ErrInvalidParam)
	if ok && e != nil 
		//...
	

	//类型选择机制,对不同类型异常处理
	if err != nil 
		switch err.(type) 
		case *ErrInvalidParam:
			//..
			return
		default:
			//...
			return
		
	

golang内置类型和内置函数(代码片段)

golang内置类型和内置函数是不需要引入包直接可用的golang内置类型:数值类型stringint,unintfloat32,float64boolarray有长度的complex64,complex128引用类型(指针类型)slicechanmapgolang内置函数append--向数组,slice里添加元素,返回新的数组... 查看详情

golang中的内置函数(代码片段)

...并不需要引入相关Package就可以直接使用该类函数。在Go的源码builtin包的builtin.go中定义Go所有的内置函数;但该文件仅仅是定义描述出了所有内置函数,并不包含函数的任何实现代码,该文件除了定义了内置函数还定义了部分内... 查看详情

不得不知道的golang之sync.mutex互斥锁源码分析(代码片段)

针对Golang1.9的sync.Mutex进行分析,与Golang1.10基本一样除了将panic改为了throw之外其他的都一样。源代码位置:syncmutex.go。可以看到注释如下:Mutexcanbein2modesofoperations:normalandstarvation.InnormalmodewaitersarequeuedinFIFOorder,butawokenupwa 查看详情

orb_slam3源码阅读笔记(代码片段)

LoopClosing线程1LoopClosing线程的创建    LoopClsing线程的创建与启动和LocalMapping线程一样,该线程的核心也在于Run()函数,以下对LoopClosing线程进行逐步的分析。创建LoopClosing对象mpLoopClosermpLoopCloser=newLoopClosing(mpAtlas,mpKeyFrameData... 查看详情

golangwaitgroup源码分析(代码片段)

针对Golang1.9的sync.WaitGroup进行分析,与Golang1.10基本一样除了将panic改为了throw之外其他的都一样。源代码位置:sync\waitgroup.go。结构体typeWaitGroupstructnoCopynoCopy//noCopy可以嵌入到结构中,在第一次使用后不可复制,使用govet作为检测使... 查看详情

arraylist源码分析

文章目录​​1、数组介绍​​​​2、ArrayList源码分析​​​​1.构造方法​​​​2.数据插入​​​​3.数据删除​​​​4.ArrayList的迭代器​​1、数组介绍数组是数据结构中很基本的结构,很多编程语言中都内置数组数组是一... 查看详情

zookeeper源码阅读(十八)选举之快速选举算法fastleaderelection(代码片段)

...经分析了选举过程中的一些实体类和网络IO相关的机制与源码,这一节将会对zookeeper选举的核心类FastLeaderElection进行分析。FastLeaderEleaction基本结构可以看到FastLeaderElection的基本结构还是比较清晰的,主要从新的成员变量类和内部... 查看详情

golang源码学习:调度逻辑maingoroutine的创建(代码片段)

接上一篇继续分析一下runtime.newproc方法。函数签名newproc函数的签名为newproc(sizint32,fn*funcval)siz是传入的参数大小(不是个数);fn对应的是函数,但并不是函数指针,funcval.fn才是真正指向函数代码的指针。//go/src/runtime/runtime2.gotypefun... 查看详情

android逆向整体加固脱壳(dexclassloader加载dex流程分析|dexfileloaddexfile函数|构造函数|opendexfile函数)(代码片(代码片段)

...ile|loadDexFile分析)中,介绍了DexPathList中通过File生成DexFile的源码,在makeDexElements中调用了loadDexFile方法,在loadDexFile又有调用了DexFile.loadDexFile函数,用于生成DexFile实例对象;本博客中介绍DexFile相关源码;一、DexFile.loadDexFile函数分析在DexPa... 查看详情

okhttp基本使用&源码分析(代码片段)

本文介绍了OkHttp的基本使用以及源码分析,强烈建议配合源码进行阅读,否则会不知所云!!!第一次写源码分析类文章,辛苦各位老铁指正本文基于OkHttp3.11.0版本进行分析,查看源码时请对应,... 查看详情

golang中container/list包源码分析

golang源码包中container/list实际上是一个双向链表提供链表的一些基本操作,下面就结合定义和接口进行下说明1.定义//Elementisanelementofalinkedlist.typeElementstruct{//Nextandpreviouspointersinthedoubly-linkedlistofelements.//Tosimplifytheimplementa 查看详情

如何读代码

...解程序实现的功能及程序的组成模块等。逐行分析。逐行阅读代码,尽量弄清每一句的 查看详情

golang内置函数new()

...它的返回值是一个指向新分配的t类型的零值的指针。在golang的代码定义如下:funcnew(tType)*Typestrut{} 直接使用struct{}来初始化strut时,返回的是一个struct类型的值,而不是指针两者是不一样的 golang的new和make主要区别 查看详情

django源码分析之server(代码片段)

乍见Django内置的server基本包括两部分:django.core.servers和django.core.handlers相识servers.basehttp是Django自身提供的一个用于开发测试的server模块,其中提供的WSGIServer、ServerHandler、WSGIRequestHandler其实都是属于WSGIserver,django只不过是对pytho... 查看详情

js菜鸟进阶-jquery源码分析-基本架构

导读:本人JS菜鸟一枚,为加强代码美观和编程思想。所以来研究下jQuery,有需要进阶JS的同学很适合阅读此文!我是边看代码(jquery2.2.1),边翻“javascript高级程序设计”写的,有很多基本知识点我都写了书本对应的章节... 查看详情

golang的goroutine调度机制

...664一直对goroutine的调度机制很好奇,最近在看雨痕的golang源码分析,(基于go1.4)感觉豁然开朗,受益匪浅;去繁就简,再加上自己的一些理解,整理了一下~~调度器主要基于三个基本对象上,G,M,P(定义在源码的src/runtime/runtime.h... 查看详情

rxjava源码分析&实践rxjava基本原理分析之订阅流(代码片段)

...使用代码入手,去结合自己已有的知识体系,加查阅部分源码验证的方式,来一起探索一下Rxjava实现的基本原理。为了本文原理分析环节,可以被更多的人理解、学习,所以小编从初学者的角度,从使用入手,一点点的分析了其... 查看详情

golang之goroutine

参考技术A阅读前提:基本了解进程与线程定义与区别我们知道程序的运行顺序是根据指令语句的顺序来执行的当我这样执行时假设这两个函数没有调用其他函数只是简单的输出(fun1输出1-5fun2输出6-10)那么程序执行时先执行fun1函... 查看详情