乐趣区

关于编程语言:Go语言学习查缺补漏ing-Day6

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

退出移动版