共计 1584 个字符,预计需要花费 4 分钟才能阅读完成。
作者:ReganYue
起源:恒生 LIGHT 云社区
Go 语言学习查缺补漏 ing Day6
一、构造体嵌套时领有同名办法的状况
咱们来看一看上面这段代码代表的含意:
package main
import ("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 main
import ("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 main
import ("fmt")
func main() {
i := 888
defer func() { fmt.Println(i) }()
i = i + 8888
}
这样输入后果就是 9776。
因为这样保留的正本是函数指针,所以值变动最终后果也会变动。
三、截取切片后的长度和容量问题
咱们来看一看这段代码:
package main
import ("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 没有被申明。