editor php Xinyi hari ini memperkenalkan kepada anda kekangan jenis Go yang menerangkan tingkah laku struktur berubah. Dalam bahasa Go, kita boleh menggunakan jenis antara muka untuk menentukan set kaedah dan mengehadkan jenis parameter masuk melalui kekangan jenis. Kaedah ini boleh melakukan semakan jenis pada masa penyusunan untuk memastikan keselamatan dan kebolehpercayaan kod. Dengan menggunakan jenis antara muka dan kekangan jenis secara rasional, kami boleh mencapai fleksibiliti dan skalabiliti kod, serta meningkatkan kebolehselenggaraan dan kebolehbacaan program. Seterusnya, mari kita lihat dengan lebih dekat cara menggunakan kekangan jenis Go untuk menerangkan tingkah laku struct boleh ubah.
Saya ingin mentakrifkan fungsi generik di mana kekangan jenis menerangkan tingkah laku struktur boleh ubah.
Apa yang saya maksudkan dengan "tingkah laku boleh ubah" ialah antara muka seperti ini:
type Unmarshaler interface { Unmarshal(data []byte) error }
...Pelaksanaannya kelihatan seperti ini:
type Foo struct { Content string } func (f *Foo) Unmarshal(data []byte) error { f.Content = string(data) return nil }
Panggil kaedah antara muka akan mengubah struktur .
Apa yang saya mahu lakukan ialah mentakrifkan fungsi generik di mana kekangan jenis ialah antara muka di atas. Fungsi generik bertanggungjawab untuk memulakan contoh jenis konkrit, kemudian mengubahnya menggunakan kaedah antara muka dan mengembalikannya.
func Unmarshal[T Unmarshaler](data []byte) (T, error) { var m T return m, m.Unmarshal(data) }
Jadi saya mahu boleh memanggil fungsi generik ini menggunakan jenis Foo.
func main() { foo, err := Unmarshal[*Foo]([]byte("hello")) if err == nil { log.Println(foo.Content) // hello } else { log.Fatal(err) } }
Saya perlu lulus *Foo
作为类型参数,因为只有指向 Foo
的指针才实现 Unmarshaler
接口。但是,当 Foo 的 Unmarshal
方法收到 f
的 nil
值时,就会出现恐慌。这对我来说都是有意义的,因为 var m T
将使指向 Foo
nilai penunjuk sifar, iaitu sifar. Tetapi saya tidak pasti sama ada saya telah menemui jalan buntu?
https://go.dev/play/p/H5s59NWNiDA
Sebaik-baiknya saya boleh menerangkannya, saya menghadapi masalah ini apabila kekangan jenis saya menerangkan beberapa kelakuan struct boleh ubah dan fungsi generik saya ingin memulakan dan kemudian mengubah instance struct. Adakah ini mungkin? Adakah terdapat cara yang lebih baik untuk membina ini?
Masalah utama ialah mencipta nilai untuk jenis tertentu T
创建有用的值。有几种方法可以做到这一点: m := make(T)
(地图和频道)等。您可以使用 reflect
pakej, tetapi lebih mudah untuk membiarkan pemanggil melepasi nilai sebagai parameter.
func Unmarshal[T Unmarshaler](m T, data []byte) (T, error) { return m, m.Unmarshal(data) }
Panggil fungsi seperti ini:
foo, err := Unmarshal(&Foo{}, []byte("hello"))
https://www.php.cn/link/8eb51d0a68e9373df41f88e5b551d4a3
Atas ialah kandungan terperinci Kekangan taip Go yang menerangkan kelakuan struktur boleh ubah. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!