Dalam Go, penunjuk adalah penting untuk bekerja dengan pembolehubah. Walau bagaimanapun, memahami nuansa antara jenis penunjuk yang berbeza boleh menjadi mencabar. Artikel ini meneroka senario tertentu yang mempamerkan perbezaan antara penunjuk dan cara ia mempengaruhi output apabila menggunakan pemformatan lalai dalam pakej fmt.
Coretan kod berikut menunjukkan isu:
type Test struct { Test string } var Models = map[string]interface{}{ "test": newTest(), } func main() { test1 := Test{} fmt.Println("Test 1: ") fmt.Printf("%v", test1) fmt.Println() fmt.Println("Test 1 as pointer: ") fmt.Printf("%v", &test1) fmt.Println() test2 := Models["test"] fmt.Println("Test 2: ") fmt.Printf("%v", test2) fmt.Println() fmt.Println("Test 2 as pointer: ") fmt.Printf("%v", &test2) } func newTest() Test { var model Test return model }
Apabila melaksanakan kod, anda akan melihat perbezaan dalam output apabila mencetak test2 berbanding test1 sebagai penunjuk. Output untuk test1 sebagai penuding ialah rentetan kosong, manakala output untuk test2 sebagai penuding ialah perwakilan perenambelasan alamat.
Fungsi fmt.Printf menggunakan %v kata kerja untuk pemformatan lalai, yang memilih format tertentu berdasarkan jenis nilai yang dicetak. Untuk penunjuk, format lalai ialah perwakilan heksadesimal alamat.
Dalam kes pertama (ujian1 sebagai penunjuk), nilai yang dicetak ialah penunjuk kepada struct Ujian. Walau bagaimanapun, memandangkan struct dimulakan dengan nilai sifar, output adalah kosong.
Dalam kes kedua (test2 sebagai penunjuk), nilai yang dicetak ialah penunjuk kepada antara muka{}. Sebelum mencapai kata kerja %v, nilai telah melalui pembalut tambahan di dalam antara muka lain{}, yang kemudiannya menghala ke Model["ujian"]. Memandangkan nilai yang akhirnya dicetak ialah penunjuk kepada antara muka{}, pemformatan lalai untuk penunjuk digunakan dan anda mendapat perwakilan perenambelasan alamat.
Untuk menangani isu ini, seseorang perlu menggunakan penegasan jenis untuk mengekstrak struct Ujian sebenar daripada test2. Ini boleh dicapai dengan:
t2 := Models["test"] test2 := t2.(Test) // test2 is now of type Test
Dengan penegasan jenis, pembolehubah test2 kini menunjuk kepada struct Test, dan anda boleh mencetaknya seperti test1.
Sebagai alternatif, seseorang boleh menggunakan penunjuk kepada Uji terus dengan menyimpan *Nilai ujian dalam peta:
var Models = map[string]*Test{ "test": newTest(), }
Pendekatan ini menghapuskan keperluan untuk penegasan jenis dan pembalut dalam antara muka{}, dengan itu mengelakkan perwakilan perenambelasan alamat.
Atas ialah kandungan terperinci Bagaimanakah `fmt.Printf` dan Jenis Penunjuk Go Berinteraksi, dan Mengapa Mereka Menghasilkan Output Berbeza untuk Jenis Penunjuk Berbeza?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!