Kekeliruan Antara Muka Peretas dengan Println: Memahami Objek Berasaskan Nilai lwn. Berasaskan Penunjuk
Soalan:
Dalam senario di mana objek melaksanakan antara muka Stringer, mengapa bukankah kaedah String objek akan digunakan apabila menggunakan fmt.Println jika objek berasaskan nilai?
Contoh Kod:
Pertimbangkan kod Go berikut:
type Car struct { year int make string } func (c *Car) String() string { return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year) } func main() { myCar := Car{year: 1996, make: "Toyota"} fmt.Println(myCar) }
Apabila myCar ialah penunjuk, kaedah String akan digunakan seperti yang diharapkan. Walau bagaimanapun, apabila myCar ialah nilai, pemformatan Go lalai digunakan sebaliknya.
Jawapan:
Sebab bagi tingkah laku ini terletak pada cara antara muka Go berfungsi. Apabila anda menentukan jenis yang melaksanakan antara muka (Stringer, dalam kes ini), Go menjangkakan jenis itu ialah jenis antara muka yang tepat. Apabila anda menghantar nilai jenis Car ke fmt.Println, ia secara tersirat ditukar kepada antara muka{} dan tiada jenis Kereta dalam sistem jenis{} antara muka. Sebaliknya, ia adalah jenis *Kereta (penunjuk ke Kereta).
Fungsi fmt.Println menggunakan suis jenis untuk menentukan cara mencetak nilai berdasarkan jenisnya. Untuk antara muka Stringer, ia menyemak sama ada nilai melaksanakan kaedah String. Memandangkan Kereta (berasaskan nilai) tidak melaksanakan String, pemformatan lalai digunakan. Walau bagaimanapun, apabila anda memanggil myCar.String() secara eksplisit, pengkompil menukarnya secara automatik kepada (&myCar).String(), yang mempunyai *Jenis Kereta yang betul dan menggunakan kaedah pemformatan yang diingini.
Untuk memastikan bahawa objek diformatkan seperti yang dikehendaki tanpa mengira jenisnya, anda mempunyai dua pilihan:
Atas ialah kandungan terperinci Mengapa fmt.Println Tidak Mengunakan Kaedah Rentetan Antara Muka Stringer Saya Apabila Melepasi Objek Berasaskan Nilai?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!