首頁 > 後端開發 > Golang > 主體

為什麼當嵌入與 `String()` 方法衝突的類型時,Go 的 `fmt.Println` 會產生意外的輸出?

Patricia Arquette
發布: 2024-11-24 09:08:10
原創
296 人瀏覽過

Why Does Go's `fmt.Println` Produce Unexpected Output When Embedding Types with Conflicting `String()` Methods?

嵌入類型的意外 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)
}
登入後複製

當執行此程式碼,它會產生以下輸出:

{name: John Doe, age: 35 3 Construction}
登入後複製

這個結果可能看起來很混亂,因為在嵌入類型Person 和中定義了多個String() 方法納稅人。但是,透過以下規則可以解決歧義:

  • 如果多個嵌入類型定義了String() 方法,則它被視為“非法選擇器”,這意味著無法直接存取它(透過呼叫Engineer .String(),例如)。
  • 因此,沒有String() 方法被提升為嵌入類型(Engineer),因此預設格式(列印欄位
  • 但是,當fmt 套件嘗試為Engineer 數值產生預設字串表示形式時,它會檢查該值是否實作fmt.Stringer 介面(具有String() 方法)。 fmt.Stringer,因此呼叫其 String() 方法來產生欄位(名稱和欄位)的字串表示形式年齡)。
  • 刪除 Person.String() 方法或 TaxPayer.String() 方法可以解決歧義,允許將剩餘的 String() 方法用於預設格式。

此行為的關鍵要點是,只有在定義了單一、明確的方法時,嵌入類型才會提升其 String() 方法。如果存在多個方法,則嵌入類型沒有提升的 String() 方法,並且使用預設格式。

以上是為什麼當嵌入與 `String()` 方法衝突的類型時,Go 的 `fmt.Println` 會產生意外的輸出?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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