新聞中心
大家好,我是煎魚。

前段時(shí)間正在瘋狂寫代碼的時(shí)候,突然有一個(gè)讀者給我提了一個(gè)問題,讓我有了一定的興趣:
我還是比較感興趣的,因?yàn)槭巧a(chǎn)環(huán)境、有代碼,且整組人都懵逼的問題。
在征求了小伙伴的意見后,今天分享出來,大家也思考一下原因,一起規(guī)避這個(gè) “坑”。
案例一
代碼示例如下:
- type MyErr struct {
- Msg string
- }
- func main() {
- var e error
- e = GetErr()
- log.Println(e == nil)
- }
- func GetErr() *MyErr {
- return nil
- }
- func (m *MyErr) Error() string {
- return "腦子進(jìn)煎魚了"
- }
請(qǐng)思考一下,這段程序的輸出結(jié)果是什么?
該程序所調(diào)用的 GetErr 方法所返回的是 nil,而外部判斷是 e == nil,因此最終的輸出結(jié)果是 true,對(duì)嗎?
輸出結(jié)果如下:
- 2021/04/04 08:39:04 false
答案是:false。
案例二
代碼示例如下:
- type Base interface {
- do()
- }
- type App struct {
- }
- func main() {
- var base Base
- base = GetApp()
- log.Println(base)
- log.Println(base == nil)
- }
- func GetApp() *App {
- return nil
- }
- func (a *App) do() {}
請(qǐng)思考一下,這段程序的輸出結(jié)果是什么?
該程序調(diào)用了 GetApp 方法,該方法返回的是 nil,因此其賦值的 base 也是 nil。因此判斷 base == nil 的最終輸出結(jié)果是 和 true,對(duì)嗎?
輸出結(jié)果如下:
- 2021/04/04 08:59:00
- 2021/04/04 08:59:00 false
答案是: 和 false。
為什么
為什么,這兩段 Go 程序是怎么回事...也太反直覺了?其背后的原因本質(zhì)上還是對(duì) Go 語言中 interface 的基本原理的理解。
在案例一中,雖然 GetErr 方法確實(shí)是返回了 nil,返回的類型也是具體的 *MyErr 類型。但是其接收的變量卻不是具體的結(jié)構(gòu)類型,而是 error 類型:
- var e error
- e = GetErr()
在 Go 語言中, error 類型本質(zhì)上是 interface:
- type error interface {
- Error() string
- }
因此兜兜轉(zhuǎn)轉(zhuǎn)又回到了 interface 類型的問題,interface 不是單純的值,而是分為類型和值。
所以傳統(tǒng)認(rèn)知的此 nil 并非彼 nil,必須得類型和值同時(shí)都為 nil 的情況下,interface 的 nil 判斷才會(huì)為 true。
在案例一中,結(jié)合代碼邏輯,更符合場(chǎng)景的是:
- var e *MyErr
- e = GetErr()
- log.Println(e == nil)
輸出結(jié)果就會(huì)是 true。
在案例二中,也是一樣的結(jié)果,原因也是 interface。不管是 error 接口(interface),還是自定義的接口,背后原理一致,自然也就結(jié)果一致了。
總結(jié)
今天這篇文章,相當(dāng)于是《Go 面試題:Go interface 的一個(gè) “坑” 及原理分析》的變形了,畢竟是生產(chǎn)環(huán)境的代碼改造而來,更貼合真實(shí)的實(shí)際場(chǎng)景。
下意識(shí)的直覺有時(shí)候不是絕對(duì)正確的,我們要正確的理解 Go 語言中的那些知識(shí)點(diǎn),才能更好地實(shí)現(xiàn)早下班的理想和愿景。
分享名稱:生產(chǎn)環(huán)境遇到一個(gè)Go問題,整組人都懵圈了...
標(biāo)題路徑:http://www.5511xx.com/article/dhoiogd.html


咨詢
建站咨詢
