Limpahan Tindanan Rekursif Tak Terhingga dengan Struktur Bersarang dalam Fungsi String()
Pertimbangkan struct bersarang berikut:
type ConfigOne struct { Daemon daemon } type daemon struct { Loglevel int Logfile string }
Sekarang, mari kita anggap kita mentakrifkan kaedah rentetan String() pada jenis ConfigOne:
func (c ConfigOne)String() string { return fmt.Sprintf("%+v\n", c) }
Kaedah String() ini cuba mengembalikan nilai elemen struct bersarang dengan menggunakan penentu format % v. Walau bagaimanapun, ini membawa kepada ralat limpahan tindanan rekursif tak terhingga.
Sebab ralat ini ialah penentu format %v dan % v menggunakan nilai fungsi String() jika jenis itu melaksanakannya. Oleh itu, menggunakan % v pada jenis dalam fungsi String() untuk jenis itu mencipta panggilan rekursif yang tidak pernah tamat.
Untuk mengelakkan ralat ini, anda tidak seharusnya menggunakan % v dalam fungsi String() anda. Sebaliknya, anda harus membina rentetan anda secara manual dengan mengakses dan memformat nilai medan secara eksplisit:
func (c ConfigOne)String() string { return fmt.Sprintf("Loglevel: %d, Logfile: %s\n", c.Daemon.Loglevel, c.Daemon.Logfile) }
Fungsi String() yang diubah suai ini tidak lagi menyebabkan rekursi tak terhingga dan ia mengeluarkan nilai elemen struct bersarang dengan betul .
Sebagai alternatif, anda boleh mengatasi kaedah String() dalam struct daemon bersarang untuk mengelakkan rekursi:
func (d daemon)String() string { return fmt.Sprintf("Loglevel: %d, Logfile: %s\n", d.Loglevel, d.Logfile) }
Dengan mengatasi kaedah String() dalam struct bersarang, anda memecahkan rantai panggilan rekursif dan memastikan bahawa fungsi String() hanya mengeluarkan nilai struct bersarang itu sendiri, bukannya semua struktur yang mengandunginya.
Atas ialah kandungan terperinci Mengapakah Menggunakan `% v` dalam Kaedah `String()` Membawa kepada Rekursi Infiniti dengan Struct Bersarang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!