首頁 > 後端開發 > Golang > 為什麼 Go 在編譯時不偵測嵌入式結構的 String() 方法呼叫中的歧義?

為什麼 Go 在編譯時不偵測嵌入式結構的 String() 方法呼叫中的歧義?

Linda Hamilton
發布: 2024-11-26 03:05:10
原創
208 人瀏覽過

Why Doesn't Go Detect Ambiguity in String() Method Invocation for Embedded Structs at Compile Time?

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():

  • fmt 呼叫 Person.String(),因為它在 Engineer 類型中具有最淺的深度。
  • 輸出為:「{name: John Doe,年齡:35 3 建築}"

無Person.String():

  • fmt 呼叫TaxPayer.String(),因為它是唯一升級的String() 方法。
  • 輸出為:「3」

沒有兩個String()方法:

  • 不能從嵌入類型提升String () 方法。
  • fmt 列印預設欄位值:「{{John Doe 35} {3}建構}"

這些場景突顯了 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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板