Golang 學習——如何判斷 Golang 介面是否實現?

相守之路發表於2020-05-05

在看一個底層庫的的時候,看到了一個比較奇怪的寫法,於是乎有了本文。

主要探討兩個問題:

1.利用編譯來判斷Golang介面是否實現
2.延伸出的make和new的區別

1.利用new()來判斷Golang介面是否實現

看了一個底層通用連結池的庫,有這麼一行程式碼:

var _ Pooler = new(WeightedRoundRobin)

需要解釋的是:Pooler是一個介面型別。

type Pooler interface {
       // ...
}

剛開始看是疑惑的,為什麼new了之後是要拋棄調?

後面發現這個是為了驗證某某介面是否被實現了?

多看了一些程式碼後發現很多地方有類似這樣的寫法。

至此Get到了。

解釋:如果說次介面沒有被實現,那麼一方面ide會有紅橫線出現,另一方面在編譯的時候會出現報錯。兩方面的提示來保證寫底層程式碼的介面是有被實現的。

2.延伸出的make和new的區別

和小夥伴討論期間,跑出了這麼一個問題:“可以使用go test的方式,去_test.go檔案中定義一個介面,來判斷就好了。上文判斷會存在浪費記憶體的情況

這邊兩個點:
1.go test的方式肯定是可行的。
但是並沒法保證程式設計師會真的記住去執行進行檢測(非強制必須走的流程)。但是直接通過前文方式,是會在編譯的時候拋錯的,這個是必須走的流程,所以更推薦前文的方式。

2.new佔記憶體?
new:申請了記憶體,但是不會將記憶體初始化,只會將記憶體置零,返回一個指標。

make:申請了記憶體,返回已初始化的結構體的零值。
在這裡插入圖片描述
回到正文,雖然申請了記憶體,但佔的記憶體其實並不多,並且在初始化後的一次gc中便會回收。所以還好。
同時也不存在效率問題,編譯型語言,你懂的。

同時驗證一個new和取地址和make的區別的程式碼:

func main() {
    a1 := new([]int)
    a2:= &[]int{}
    a3:= make([]int,0)

    fmt.Println(a1,a2,a3,a1==a1)
}

附錄:Golang new和 make的區別

擴充套件
對於記憶體的佔用,今天看到一種寫法。

var _ Tester = (*Test)(nil)

這樣寫和new的區別在於:new是編譯的時候檢查,這樣寫是執行的時候檢查

轉載自:如何判斷Golang介面是否實現?

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章