為什么Go里值為nil可以調(diào)用函數(shù)原理分析
起因
最近在我們 Go 的技術(shù)交流群里,有一個小伙伴提了一個程序方面的問題,還挺有意思的,分享給大家。
示例
示例程序如下:
type T struct{} func (t *T) Hello() string { if t == nil { fmt.Println("腦子進(jìn)煎魚了") return "" } return "煎魚進(jìn)腦子了" } func main() { var t *T t.Hello()
這段程序的運(yùn)行結(jié)果是什么?
從程序的分析來看,變量 t
并沒有初始化,只是聲明了類型。然后就直接調(diào)用了 Hello
方法,像是 nil 調(diào)用函數(shù),理論上應(yīng)該出現(xiàn)恐慌(panic)。
運(yùn)行結(jié)果是:
panic: runtime error: invalid memory address or nil pointer dereference
對不對呢?
顯然,真正的運(yùn)行結(jié)果是:
腦子進(jìn)煎魚了
請你思考一下,想想這是為什么?
原理
問題的原因是:很多小伙伴認(rèn)為變量 t
的值都是 nil 了,不應(yīng)該還能調(diào)用到才對。
更抽象化來講,就是 ”程序是如何檢查對象指針來尋找和調(diào)度所需函數(shù)“。
實(shí)際上,在 Go 中,表達(dá)式 Expression.Name
的語法,所調(diào)用的函數(shù)完全由 Expression
的類型決定。
其調(diào)用函數(shù)的指向不是由該表達(dá)式的特定運(yùn)行時(shí)值來決定,包括我們前面所提到的 nil。
具體如下:
func (p *Sometype) Somemethod (firstArg int) {}
本質(zhì)上是:
func SometypeSomemethod(p *Sometype, firstArg int) {}
這么一看,其實(shí)大家應(yīng)該都明白了。
上述入?yún)?nbsp;p *Sometype
是有具體上下文類型的,自然而然也就能調(diào)用到相應(yīng)的方法。如果是沒有任何上下文類型的,例如:nil.Somemethod
方法來調(diào)用,那肯定就是無法運(yùn)行的。
與值是不是 nil,是什么,沒有太多直接的影響。只要有預(yù)期類型的上下文就可以了。
總結(jié)
今天給大家分享了一個 Go 語言里面的一個小細(xì)節(jié),平時(shí)可能很多人沒注意到,畢竟 IDE 也會標(biāo)黃,會避開這個問題點(diǎn)。
在理解 Go 的設(shè)計(jì)和思考上,我們是需要清晰其背后的原因和邏輯的,也就是類型決定其調(diào)用,而不是值(容易誤判)。
以上就是為什么Go里值為nil可以調(diào)用函數(shù)原理分析的詳細(xì)內(nèi)容,更多關(guān)于Go值nil調(diào)用函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang中函數(shù)(Function)和方法(Method)的區(qū)別詳解
在Golang中,大家必然會頻繁使用到函數(shù)(Function)和方法(Method),但是有的同學(xué)可能并沒有注意過函數(shù)和方法的異同點(diǎn),函數(shù)和方法都是用來執(zhí)行特定任務(wù)的代碼塊,雖然很相似,但也有很大的區(qū)別,所以本文將詳細(xì)講解函數(shù)和方法的定義以及它們的異同點(diǎn)2023-07-07Golang-如何判斷一個?interface{}?的值是否為?nil
interface?的內(nèi)部實(shí)現(xiàn)包含了兩個字段,一個是?type,一個是?data,這篇文章主要介紹了Golang-如何判斷一個interface{}的值是否為nil,需要的朋友可以參考下2023-05-05Go語言規(guī)范context?類型的key用法示例解析
這篇文章主要為大家介紹了Go語言規(guī)范context?類型的key用法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08GoLang并發(fā)編程中條件變量sync.Cond的使用
Go標(biāo)準(zhǔn)庫提供Cond原語的目的是,為等待/通知場景下的并發(fā)問題提供支持,本文主要介紹了Go并發(fā)編程sync.Cond的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下2023-01-01