本文转载自微信公众号《我的脑子是炸鱼》,作者陈建宇。转载本文请联系脑筋急转弯公众号。大家好,我是炸鱼。最近在我们的围棋技术交流群里,有小伙伴提了一个程序相关的问题,挺有意思的,分享给大家。示例示例程序如下:typeTstruct{}func(t*T)Hello()string{ift==nil{fmt.Println("大脑是炸鱼")return""}return"炸鱼已经进入brain"}funcmain(){vart*Tt.Hello()这个程序的运行结果是什么?从程序分析,变量t并没有被初始化,只是声明了类型。然后直接调用hello方法,就像用nil调用函数一样,理论上应该会出现panic。运行结果是:panic:runtimeerror:invalidmemoryaddressornilpointerdereference对吧?很显然,真正的手术结果是:你脑子炸了。请大家想一想,想一想这是为什么?值都是nil,应该调用不了。更抽象地说,就是“程序如何通过检查对象指针来找到并派发需要的函数”。事实上,在Go的表达式Expression.Name的语法中,调用的函数完全由Expression的类型决定。指向调用函数的指针不是由表达式的具体运行时值决定的,包括我们前面提到的nil。具体如下:func(p*Sometype)Somemethod(firstArgint){}本质上就是:funcSometypeSomemethod(p*Sometype,firstArgint){}这样大家应该都明白了。上面的入参p*Sometype有特定的上下文类型,自然可以调用对应的方法。如果在没有任何上下文类型的情况下调用它,例如:nil.Somemethod方法,它肯定不会起作用。对值是多少没有太大的直接影响,无论它是否为零。只要有预期的上下文类型就应该没问题。小结今天给大家分享一个Go语言的小细节。很多人可能没有注意到。毕竟IDE也会把它标记为黄色,避免这个问题。在理解Go的设计和思路时,我们需要明确其背后的原因和逻辑,即类型决定其调用,而不是值(容易误判)。
