Go 中嵌入結構的奇怪方法呼叫:理解 String()
在 Go 中,嵌入結構繼承其嵌入類型的方法。但是,當多個嵌入類型定義具有相同名稱的方法時,就會出現歧義。讓我們特別關注 String() 方法來探索這種行為。
在提供的範例程式碼中:
type Engineer struct { Person TaxPayer Specialization string } type Person struct { Name string Age int } func (p Person) String() string { return fmt.Sprintf("name: %s, age: %d", p.Name, p.Age) } type TaxPayer struct { TaxBracket int } func (t TaxPayer) String() string { return fmt.Sprintf("%d", t.TaxBracket) }
使用 fmt.Println(engineer) 列印 Engineer 結構體時,輸出會根據嵌入類型中是否存在 String() 方法而變更。
與Person.String():
無Person.String():
沒有兩個String()方法:
這些場景突顯了 Go 中提升方法的深度規則和歧義解決。然而,問題出現了,為什麼當存在多個深度為零的 String() 方法時,在編譯時沒有偵測到歧義。
不明確的選擇器檢查:
通常,當嘗試使用不明確的選擇器呼叫方法(例如Engineer.Foo())時,會發生編譯時錯誤。但是,使用名為 String() 的方法不會發生這種情況。
原因:
在未明確呼叫其 String() 方法的情況下列印值時, fmt.Println函數檢查該值是否實作 fmt.Stringer。然後它呼叫已實作的 String() 方法。由於所有 Go 類型預設都隱含實作 Stringer (https://golang.org/doc/go1.19#fmt),因此任何型別總是有提升的 String() 方法。
結論:
嵌入結構的方法調用的歧義性是由於深度規則和用於打印的 String() 方法的特殊處理而產生的價值觀。透過了解這些規則以及方法提升中的細微差別,開發人員可以避免意外行為並保持 Go 程式中程式碼的清晰度。
以上是為什麼 Go 在編譯時不偵測嵌入式結構的 String() 方法呼叫中的歧義?的詳細內容。更多資訊請關注PHP中文網其他相關文章!