开启掘金成长之旅!这是我参与「掘金日新计划 · 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])
}
参考答案:这里的
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面试中会出现的问题,接下来会继续分享其他的习题的相关知识,对于一个刚入门的我来说,还有许多地方需要学习,有错误的地方欢迎大家指出,共同进步!!