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
Lepaskan: 2024-11-30 07:28:11
asal
363 orang telah melayarinya

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)
}
Salin selepas log masuk

Keluaran kod ini ialah:

{name: John Doe, age: 35 3 Construction}
Salin selepas log masuk

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

3
Salin selepas log masuk

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

{{John Doe 35} {3} Construction}
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan