浅谈Go与习题(二十八)

62 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 18 天,点击查看活动详情

今天来学习下Go常见的习题问题(二十八),也是面试中可能会遇到的,让我们来一起学习吧~

切片问题

观察下列代码,判断存在什么隐患?

func get() []byte {
    raw := make([]byte, 100)
    fmt.Println(len(raw), cap(raw), &raw[0])
    return raw[:3]
}

func main() {
    data := get()
    fmt.Println(len(data), cap(data), &data[0])
}

image.png 参考答案:这里的get()函数返回的切片与原切片共用底层数组,如果在调用函数里面获取返回的切片,并且进行修改返回的切片,将会影响到原切片的数据,为了避免这个隐患的发生,我们可以使用copy()函数进行修改,代码如下:

func get() []byte {
    raw := make([]byte, 100)
    fmt.Println(len(raw), cap(raw), &raw[0])
    res := make([]byte, 3)
    copy(res, raw[:3])
    return res
}

func main() {
    data := get()
    fmt.Println(len(data), cap(data), &data[0])
}

值类型接收

观察下列代码,判断输出结果是什么?为什么?

type Foo struct {
    val int
}

func (f Foo) Inc(inc int) {
    f.val += inc
}

func main() {
    var f Foo
    f.Inc(12)
    fmt.Println(f.val)
}

参考答案: 输出为空,因为使用值类型接收者定义的方法,调用成员的值用的是副本,对副本操作不会影响原来成员的值,如果需要再调用函数中修改成员的值,需要修改为指针接收者定义的方法,修改代码如下所示:

type Foo struct {
    val int
}

func (f *Foo) Inc(inc int) {
    f.val += inc
}

func main() {
    f := &Foo{}
    f.Inc(12)
    fmt.Println(f.val)  // 12
}

变量的作用域

观察下列代码,判断输出结果?为什么?

func main() {
    a := 1
    for i := 0; i < 5; i++ {
        a := a + 1
        a = a * 2
    }
    fmt.Println(a)
}

参考答案:输出1,因为for语句中的变量a重新申明,所以作用范围只能在for语句中,外部的变量a是没有发生改变

总结

今天浅谈了Go的习题(二十八),主要介绍了GO面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!