Rumah >pembangunan bahagian belakang >Golang >Mengapakah `fmt.Println()` berkelakuan berbeza dengan jenis terbenam dalam Go apabila jenis terbenam mempunyai kaedah `String()` yang bercanggah?

Mengapakah `fmt.Println()` berkelakuan berbeza dengan jenis terbenam dalam Go apabila jenis terbenam mempunyai kaedah `String()` yang bercanggah?

Patricia Arquette
Patricia Arquetteasal
2024-11-30 07:28:11380semak imbas

Why does `fmt.Println()` behave differently with embedded types in Go when the embedded types have conflicting `String()` methods?

Kaedah Ambiguous String() dengan Jenis Terbenam dalam Go

Apabila berurusan dengan jenis terbenam dalam Go, fahami gelagat String () kaedah boleh membingungkan. Mari kita mendalami tingkah laku ini berdasarkan sampel kod tertentu.

Pertimbangkan kod berikut:

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)
}

Keluaran kod ini ialah:

{name: John Doe, age: 35 3 Construction}

Walau bagaimanapun, jika Person.String() dialih keluar, output menjadi:

3

Dan jika TaxPayer.String() juga dialih keluar, output berubah kepada:

{{John Doe 35} {3} Construction}

Pada mulanya, nampaknya mesti ada kaedah String() tersirat untuk struct Jurutera. Walau bagaimanapun, ini tidak berlaku.

Kaedah String() dalam Jenis Terbenam

Apabila jenis dibenamkan dalam struktur, medan dan kaedahnya boleh diakses melalui jenis benam. "Promosi" kaedah ini boleh membawa kepada kekaburan jika berbilang jenis terbenam mentakrifkan kaedah dengan nama yang sama, seperti String().

Dalam sampel kod yang diberikan, memandangkan Orang dan Pembayar Cukai mempunyai String() kaedah, promosi kaedah ini kepada jenis Jurutera menyebabkan kekaburan. Inilah sebabnya Engineer.String() mengakibatkan ralat penyusunan.

Mengapa tiada Ralat Kekaburan Semasa Menggunakan fmt.Println()

Walaupun terdapat kekaburan dalam set kaedah Jurutera , fmt.Println(jurutera) tidak menghasilkan ralat penyusunan. Ini kerana fmt.Println() memanggil fmt.Fprint(os.Stdout, engineer).

fmt.Fprint() menyemak sama ada nilai yang diluluskan melaksanakan antara muka fmt.Stringer, yang merangkumi kaedah String() . Jika ia berlaku, String() digunakan untuk menghasilkan perwakilan rentetan nilai.

Dalam kes ini, memandangkan Orang mahupun Pembayar Cukai tidak melaksanakan fmt.Stringer, pemformatan lalai (medan struct) digunakan sebaliknya. Ini menghasilkan output yang kita lihat apabila fmt.Println(jurutera) dipanggil.

Kesimpulan

Memahami tingkah laku jenis terbenam dan promosi kaedahnya adalah penting dalam Go. Apabila berbilang jenis terbenam mentakrifkan kaedah dengan nama yang sama, ia boleh membawa kepada kekaburan, mengakibatkan ralat penyusunan. Walau bagaimanapun, apabila menggunakan fmt.Println(), pemformatan lalai digunakan apabila nilai yang diluluskan tidak melaksanakan fmt.Stringer.

Atas ialah kandungan terperinci Mengapakah `fmt.Println()` berkelakuan berbeza dengan jenis terbenam dalam Go apabila jenis terbenam mempunyai kaedah `String()` yang bercanggah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn