由于最近在 Go 1.18 中發布了泛型,我已經開始學習它們。我通常會理解這個概念,因為我過去有一些 Java 經驗。但我沒有得到一些實作細節。
例如:什么時候更適合使用any而不是interface{}? 這是一個例子:
func printInterface(foo interface{}) {
fmt.Printf("%v\n", foo)
}
func printAny[T any](foo T) {
fmt.Printf("%v\n", foo)
}
func (suite *TestSuite) TestString() {
printInterface("foo")
printAny("foo")
}
兩種實作都有效。但是,如果我嘗試nil使用any-version 進行列印,我會得到一個編譯時錯誤:
無法推斷 T。
https://go.dev/play/p/0gmU4rhhaOP
如果我嘗試nil使用interface{}-version 列印,我將不會收到此錯誤。
那么用例是any什么?與簡單地使用相比,它何時以及帶來哪些好處interface{}?
我要求提供一個具體的例子,其中一種實作在客觀上比另一種更合適和/或可以評估特定的好處。
uj5u.com熱心網友回復:
any是的別名。規格:介面型別:interface{}
為方便起見,預先宣告的型別
any是空介面的別名。
由于它是別名,因此使用哪一個都沒有關系。他們是一樣的。它們是可以互換的。您可以將一個替換為另一個,代碼含義相同。
any更短更清晰,但僅適用于 Go 1.18。
由于它們是可互換的,因此這也有效:
func printInterface(foo any) {
fmt.Printf("%v\n", foo)
}
printAny()不起作用的原因是它是帶有型別引數的泛型函式。要使用它,它必須被實體化(它的型別引數必須被分配一個已知的型別)。嘗試呼叫它時nil不攜帶型別資訊,因此無法進行實體化,型別推斷將不起作用。
如果您使用nil帶有型別資訊的值呼叫它,它將起作用,或者如果您明確指定型別引數(在Go Playground上嘗試):
printAny((*int)(nil))
printAny[*int](nil)
// Or
var r io.Reader
printAny(r)
如前所述,any可以與 互換interface{},因此如果您交換兩次出現,您將擁有相同的代碼(在Go Playground上嘗試這個):
func printInterface(foo any) {
fmt.Printf("%v\n", foo)
}
func printAny[T interface{}](foo T) {
fmt.Printf("%v\n", foo)
}
uj5u.com熱心網友回復:
any添加- 別名-的最大原因interface{}純粹是為了美觀。
any但是,您的問題與/的使用無關,interface{}而是型別推斷。正如您從這個游樂場看到的那樣,如果您使用顯式型別實體化您的函式,printAny[any](nil)它就會起作用。
如果你有一個泛型型別的函式,你需要指定型別。然而,go 編譯器非常聰明,可以為你推斷出一些型別。但nil僅憑這一點是無法推斷的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/450154.html
