内容简介:1 切片与数组2 defer3 make与new
内容
1 切片与数组
2 defer
3 make与new
4 方法与函数
1 切片和数组
- 数组和结构体都是值变量,即:如果把一个数组变量和结构体变量赋值给另外的变量,是拷贝了一份值,两者的修改互不影响;
2 . go通过切片生成另外一个切片时,两个切片共享同一个底层数组,对其中一个修改元素时,两个都会改变;
例如: a=[]int{1,2,3} b:=a[:] b[0] = 2 printLn(a[0]) —》输出:2
- 特别注意初始化切片时,如果指定了切片的长度,go会用nil来填充这个切片, 如果是基本类型则用基本类型零值填充,此后对切片通过append操作时,会在后面进行填充;所以在初始化一个切片并且指定了容量时,要注意长度初始化为0;
a := []int{1,2,3} b := make([]int, 0, len(a)) //Yes B := make([]int, len(a), len(a)) //No B1 := make([]int, 0) //Yes b1 := make([]int, 4) //No
2 defer
1.对于defer,当代码运行到defer语句时,defer后要运行的函数的入参此时已经确定了(即:defer函数的入参函数此时就被执行了,而不是到了调用是才被执行),defer下面的语句对该参数做的修改对于函数无效;;
2.如果同一个函数中有多个defer,被推迟的函数按照先进后出的顺序执行(压栈出栈),即:最后一个defer会被第一个执行;
func main(){ b() } func un(s string) { fmt.Println("leaving:", s) } func trace(s string) string { fmt.Println("enter:", s) return s } func b() { defer un(trace("b")) fmt.Println("in:", "b") a() } func a() { defer un(trace("a")) fmt.Println("in:", "a") } 打印: enter: b in: b enter: a in: a leaving: a leaving: b
3.defer 原理
- 编译期;
- 将
defer
关键字被转换runtime.deferproc
; - 在调用
defer
关键字的函数返回之前插入runtime.deferreturn
;
- 将
- 运行时:
-
runtime.deferproc
会将一个新的runtime._defer
结构体追加到当前 Goroutine 的链表头; -
runtime.deferreturn
会从 Goroutine 的链表中取出runtime._defer
结构并依次执行;
-
- 后调用的
defer
函数会先执行:- 后调用的
defer
函数会被追加到 Goroutine_defer
链表的最前面; - 运行
runtime._defer
时是从前到后依次执行;
- 后调用的
- 函数的参数会被预先计算;
- 调用
runtime.deferproc
函数创建新的延迟调用时就会立刻拷贝函数的参数,函数的参数不会等到真正执行时计算;
- 调用
3 make与new
make和new的区别:make只能用于slice map和channel,返回的是该类型初始化后的引用;new(T)返回的是指向该类型的指针。
type File struct{ name string } &File{} 《=》 new(File) ``` make只用于映射、切片和管道,并且不返回指针,如果要得到指针请使用new ``` var p *[]int = new([]int) // 得到指针 var v []int = make([]int, 0, 100) var p *[]int = new([]int) *p = make([]int, 100)
4 方法和函数
1、函数中如果入参是值参数,那么该函数只能接收值入参;如果方法中的接收器是值接收器,那么该方法可以接收值接收器和指针接收器,即:可以通过该类型接收器的值变量和指针变量调用方法;
2、函数中如果入参是指针参数,那么只能接收指针参数;如果方法中申明的接收器是指针接收器,那么该方法可以接收值接收器和指针接收器;
引用:
- 《go语言实现与设计》 https://draveness.me/golang/
- 《effective go》 https://www.kancloud.cn/kancloud/effective/72214
欢迎关注我们的微信公众号,每天学习 Go 知识
以上所述就是小编给大家介绍的《go闭坑指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。