浅谈Go与习题(十九)

80 阅读2分钟

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

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

函数比较

观察下列代码,判断是否可以通过编译?

func main() {
    var fn1 = func() {}
    var fn2 = func() {}
    if fn1 != fn2 {
       println("fn1 not equal fn2")
    }
}

参考答案:编译错误,invalid operation: cannot compare fn1 != fn2 (func can only be compared to nil)函数之间不能比较,只能和nil进行比较

不可寻址

观察下列代码,判断是否可以通过编译?

type T struct {
    w int
}
func main() {
    m := make(map[int]T)
    m[0].w = 2
    fmt.Println(m[0].w)
}

参考答案:不能通过编译,错误信息:cannot assign to struct field m[0].w in map因为map[int]struct,中的struct不可以寻址,所以不能直接赋值,go语言中不能寻址可以人为是:不可变的,临时结果和不安全的,修改代码如下:

type T struct {
    w int
}
func main() {
    m := make(map[int]T)
    w := T{1}
    m[0] = w
    fmt.Println(m[0].w)
}

指针类型receiver

观察下列代码,判断是否可以通过编译?

type X struct {}
func (x *X) test()  {
   println("hi:",x)
}
func main() {
    var a *X
    a.test()
    X{}.test()
}

参考答案:不可以通过编译,错误信息:cannot call pointer method test on Xcompiler,因为X{}不可以寻址,指针类型的receiver必须是合法指针(包括nil),才能获取实例地址,这里额外提一下如何选择方法的receiver类型?

  1. 要修改实例状态的可以使用*T
  2. 无需修改状态的小对象或者固定值T
  3. 大对象建议使用*T,减少复制成本
  4. 引用类型、字符串、函数等指针包装对象,直接用T
  5. 包含Mutex等同步字段,可以使用*T来避免锁操作无效

总结

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