作者:ReganYue
起源:恒生LIGHT云社区
Go语言学习查缺补漏ing Day6
一、构造体嵌套时领有同名办法的状况
咱们来看一看上面这段代码代表的含意:
package mainimport ( "fmt")type Student struct{}func (s *Student) sayHello() { fmt.Println("sayHello") s.sayBey()}func (s *Student) sayBey() { fmt.Println("sayBey")}type Teacher struct { Student}func (t *Teacher) sayBey() { fmt.Println("teacher sayBey")}func main() { t := Teacher{} t.sayBey()}
在这外面有一个嵌套构造体,其中Teacher是内部类型,Student是外部类型。这样就能实现外部属性,也就是这的Student的属性办法,可能被内部类型也就是Teacher领有。当然,内部属性也能够领有本人的属性、办法,如果领有了与外部类型一样名字的办法,那么同名的外部类型的办法就会失去作用。
这个例子的输入后果是什么,我想你应该晓得了:
teacher sayBey
这个例子中的sayBey()办法就是同名的办法,所以外部类型Student的这个办法会失去作用,调用就是调用Teacher中定义的sayBey()办法。
二、应用defer执行函数的一个注意事项
package mainimport ( "fmt")func sayHello(i int) { fmt.Println(i)}func main() { i := 888 defer sayHello(i) i = i + 8888}
咱们都晓得defer是在最初执行的,那么你看一看这里输入什么?
答案是:888
为什么呢?
因为程序在运行到 defer sayHello(i)
时就把函数中的参数的正本保留,这里保留的参数i的值就为888.
因而,sayHello(i)的后果并不是在主函数完结之前进行,而是在 defer
关键字调用时计算的。
怎么解决这个问题呢?
很简略,在defer时应用匿名函数就行了。
package mainimport ( "fmt")func main() { i := 888 defer func() { fmt.Println(i) }() i = i + 8888}
这样输入后果就是9776。
因为这样保留的正本是函数指针,所以值变动最终后果也会变动。
三、截取切片后的长度和容量问题
咱们来看一看这段代码:
package mainimport ( "fmt")func main() { s := []int{0, 0, 0} a := s[:0] b := s[:2] c := s[1:2:cap(s)] fmt.Println(len(a), cap(a)) fmt.Println(len(b), cap(b)) fmt.Println(len(c), cap(c))}
你感觉运行后果是什么?
答复这个问题须要理解截取操作,截取操作个别是两个参数,代表截取的起始地位和终止地位,截取的局部不包含第二个参数。而第三个参数就是更改切片的容量,然而第三个参数不能大于切片底层数组的长度。如果第一个参数省略,那代表第一个参数为0,如果第二个参数省略了,那么代表第二个参数为这个切片底层数组的长度。
四、变量申明的一个小常识
1. a, _ := f()2. a, _ = f()3. a, b := f()4. a, b = f()
如果这段代码之前a曾经被申明了,而b还没有被申明。那么下面4条语句,哪条正确,哪条谬误?
第一条是谬误的,因为a曾经被申明了,不能应用:=。
第二条正确,因为a被申明了,能够应用=赋值。
第三条也正确,当多值赋值时,在:=右边的变量如果有一个新变量,就能执行这条语句。如果:=右边都是曾经被申明的变量,那么这条语句也是谬误的。
第四条谬误,b没有被申明。