Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Penerima Penunjuk dalam Kaedah Rentetan Membawa kepada Gelung Mati dalam Pergi?

Mengapa Penerima Penunjuk dalam Kaedah Rentetan Membawa kepada Gelung Mati dalam Pergi?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-23 21:15:20745semak imbas

Why Does a Pointer Receiver in String Method Lead to a Dead Loop in Go?

Penerima Penunjuk vs Penerima Nilai dalam Kaedah Rentetan

Dalam Go, kaedah String() digunakan untuk mengawal perwakilan rentetan tersuai menaip. Apabila mentakrifkan kaedah String(), adalah penting untuk memahami perbezaan antara penerima penunjuk dan penerima nilai.

Pertimbangkan kod berikut:

type TT struct {
    a int
    b float32
    c string
}

func (t *TT) String() string {
    return fmt.Sprintf("%+v", *t)
}

Dalam kod ini, String( ) kaedah mempunyai penerima penunjuk, yang bermaksud ia beroperasi pada penunjuk kepada nilai TT. Memanggil tt.String() dengan berkesan memanggil (*tt).String().

Sekarang, pertimbangkan untuk menukar kaedah String() kepada yang berikut:

func (t *TT) String() string {
    return fmt.Sprintf("%+v", t)
}

Perubahan ini mengalih keluar penuding penerima, menjadikan kaedah String() beroperasi pada nilai jenis TT.

Mengapa ini mengakibatkan kematian gelung?

Pakej fmt menyemak sama ada nilai yang dicetak melaksanakan antara muka Stringer (atau mempunyai kaedah String()). Jika ya, ia akan memanggil kaedah itu untuk mendapatkan perwakilan rentetan. Walau bagaimanapun, dalam kes ini, kami mempunyai penerima penunjuk untuk kaedah String().

Apabila kami memanggil tt.String(), pakej fmt melepasi nilai jenis *TT. Walau bagaimanapun, kaedah String() menjangkakan nilai jenis TT. Ketidakpadanan ini menyebabkan pakej fmt memanggil kaedah String() sekali lagi, yang seterusnya akan dipanggil semula, dan seterusnya, mengakibatkan gelung tak terhingga.

Pencegahan/Perlindungan

Untuk mengelakkan gelung mati ini, pastikan jenis penerima kaedah String() sepadan dengan jenis nilai yang dihantar ke pakej fmt. Jika atas sebab tertentu anda perlu menggunakan jenis penerima yang sama, anda boleh mencipta jenis baharu menggunakan kata kunci jenis dan menukar nilai kepada jenis baharu sebelum memanggil fmt.Sprintf:

func (t TT) String() string {
    type TT2 TT
    return fmt.Sprintf("%+v", TT2(t))
}

Dengan mencipta yang baharu taip, kami mengalih keluar semua kaedah daripada jenis asas, dengan berkesan memutuskan kitaran dan membolehkan kami menghubungi fmt.Sprintf dengan selamat.

Atas ialah kandungan terperinci Mengapa Penerima Penunjuk dalam Kaedah Rentetan Membawa kepada Gelung Mati dalam Pergi?. 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