Rumah > pembangunan bahagian belakang > Golang > Mengapakah `fmt.Println` Go Menghasilkan Output Tidak Dijangka Apabila Membenamkan Jenis dengan Kaedah `String()` Bercanggah?

Mengapakah `fmt.Println` Go Menghasilkan Output Tidak Dijangka Apabila Membenamkan Jenis dengan Kaedah `String()` Bercanggah?

Patricia Arquette
Lepaskan: 2024-11-24 09:08:10
asal
361 orang telah melayarinya

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

Gelagat Kaedah Rentetan() Tidak Dijangka dengan Jenis Terbenam

Dalam Go, pembenaman membenarkan jenis memasukkan medan dan kaedah daripada jenis lain dalam strukturnya sendiri. Walau bagaimanapun, apabila berbilang jenis terbenam mentakrifkan kaedah dengan nama yang sama (seperti String()), senario tertentu boleh membawa kepada gelagat yang tidak dijangka.

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

Apabila kod ini dilaksanakan, ia menghasilkan output berikut:

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

Hasil ini mungkin kelihatan mengelirukan, kerana terdapat adalah berbilang kaedah String() yang ditakrifkan dalam jenis terbenam Orang dan Pembayar Cukai. Walau bagaimanapun, kekaburan itu diselesaikan dengan peraturan berikut:

  • Jika berbilang jenis terbenam mentakrifkan kaedah String(), ia dianggap sebagai "pemilih haram", bermakna ia tidak boleh diakses secara langsung (dengan menghubungi jurutera .String(), sebagai contoh).
  • Akibatnya, tiada kaedah String() dipromosikan kepada jenis pembenaman (Jurutera), dan dengan itu lalai pemformatan (mencetak nilai medan) digunakan.
  • Walau bagaimanapun, apabila pakej fmt cuba menghasilkan perwakilan rentetan lalai untuk nilai Jurutera, ia menyemak sama ada nilai itu melaksanakan antara muka fmt.Stringer (yang mempunyai String () kaedah).
  • Memandangkan jenis Orang melaksanakan fmt.Stringer, kaedah String()nya dipanggil untuk menghasilkan rentetan perwakilan medan (nama dan umur).

Mengalih keluar kaedah Person.String() atau kaedah TaxPayer.String() menyelesaikan kekaburan, membenarkan kaedah String() yang selebihnya digunakan untuk pemformatan lalai.

Pengambilan utama daripada tingkah laku ini ialah jenis terbenam mempromosikan kaedah String() mereka hanya jika terdapat satu, kaedah yang tidak jelas ditakrifkan. Jika berbilang kaedah wujud, jenis pembenaman tidak mempunyai kaedah String() yang dipromosikan dan pemformatan lalai digunakan.

Atas ialah kandungan terperinci Mengapakah `fmt.Println` Go Menghasilkan Output Tidak Dijangka Apabila Membenamkan Jenis dengan Kaedah `String()` 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