嵌入式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) } func main() { engineer := Engineer{ Person: Person{ Name: "John Doe", Age: 35, }, TaxPayer: TaxPayer{3}, Specialization: "Construction", } fmt.Println(engineer) }
此程式碼的輸出是「名稱:John Doe,年齡:35 3 Construction」。這種行為最初令人費解,可以透過檢查嵌入類型如何與 String() 方法互動來解釋。
嵌入類型提升
在 Go 中,嵌入類型允許包含其他類型的欄位和方法。當一個類型嵌入另一個類型時,嵌入類型的欄位和方法將提升為嵌入類型,其行為就像是在嵌入類型上定義的一樣。在我們的範例中,Engineer 類型嵌入了 Person 和 TaxPayer 類型。
方法選擇
在嵌入類型上呼叫 String() 方法時,預設行為是選擇具有該名稱的最淺(嵌套最淺)的方法。但是,如果相同深度有多個提升的 String() 方法,則選擇器表達式將變得非法,從而導致編譯時錯誤。
在提供的程式碼中,Person 和 TaxPayer 類型都具有 String()方法。因此,Engineer.String() 是非法選擇器。因此,在列印 Engineer 值時,不會直接呼叫任何 String() 方法。
fmt 套件字串產生
當沒有明確String() 時為結構類型定義的方法,fmt 套件依賴於預設的字串表示形式,其中包括列印字段值。在Engineer 結構中,這會導致輸出「name: John Doe,age: 35 3 Construction.」
刪除方法的效果
有趣的是,刪除任一Person .String() 或TaxPayer.String() 解決了歧義,允許使用剩餘的String() 方法來產生字串。這強調了在使用嵌入類型時仔細考慮方法命名約定的重要性。
結論
嵌入類型上的 String() 方法的行為強調了清晰度的需要以及定義方法時的遠見。透過了解方法選擇和提升的機制,開發人員可以避免不明確的選擇器並確保其類型的字串表示形式一致。
以上是Go 的 `String()` 方法如何與嵌入類型和多個提升方法一起運作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!