Rumah >pembangunan bahagian belakang >Golang >Mengapa fmt.Println Tidak Mengunakan Kaedah Rentetan Antara Muka Stringer Saya Apabila Melepasi Objek Berasaskan Nilai?

Mengapa fmt.Println Tidak Mengunakan Kaedah Rentetan Antara Muka Stringer Saya Apabila Melepasi Objek Berasaskan Nilai?

Susan Sarandon
Susan Sarandonasal
2024-12-06 19:35:15492semak imbas

Why Doesn't fmt.Println Invoke My Stringer Interface's String Method When Passing a Value-Based Object?

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:

  1. Laksanakan Rentetan pada Kereta (berasaskan nilai): Ini memerlukan mencipta kaedah Rentetan berasingan untuk Kereta yang beroperasi pada penerima nilai, yang akan menyebabkan penyalinan objek yang tidak perlu.
  2. Sentiasa hantar penunjuk ke fmt.Println: Dengan menggunakan fmt.Println(&myCar), anda memastikan bahawa nilai yang diluluskan mempunyai *Jenis Kereta yang betul dan kaedah String akan digunakan seperti yang dijangkakan.

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!

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