作者: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没有被申明。