Apabila bekerja dengan generik dalam Go 1.18, anda mungkin menghadapi situasi di mana anda perlu mencipta contoh baharu jenis tersuai dalam fungsi generik. Masalah berikut menunjukkan cabaran ini:
Dalam contoh kod yang disediakan, fungsi Cipta dalam struct FruitFactory bertujuan untuk mencipta contoh baharu jenis T, tetapi pada masa ini ia mengembalikan sifar. Ini mengakibatkan kesalahan pembahagian apabila cuba mengakses atribut objek.
type FruitFactory[T any] struct{} func (f FruitFactory[T]) Create() *T { // How to create non-nil fruit here? return nil } type Apple struct { color string } func example() { appleFactory := FruitFactory[Apple]{} apple := appleFactory.Create() // Panics because nil pointer access apple.color = "red" }
Untuk menyelesaikan isu, kita perlu mengubah suai fungsi Cipta untuk mengembalikan contoh jenis yang sah T. Terdapat dua pendekatan untuk mencapai ini:
Pendekatan 1 (Bukan Penunjuk Jenis)
Jika jenis tersuai bukan jenis penunjuk (seperti struct Apple), anda boleh mengisytiharkan pembolehubah yang ditaip dan mengembalikan alamatnya:
func (f FruitFactory[T]) Create() *T { var a T return &a }
Pendekatan 2 (Jenis Penunjuk)
Jika jenis tersuai ialah jenis penuding (seperti *Apple), penyelesaiannya lebih terlibat. Anda boleh memanfaatkan kuasa jenis inferens untuk mengekang jenis kilang kepada jenis penunjuk:
// Constraining a type to its pointer type type Ptr[T any] interface { *T } // The first type param will match pointer types and infer U type FruitFactory[T Ptr[U], U any] struct{} func (f FruitFactory[T,U]) Create() T { // Declare var of non-pointer type. This is not nil! var a U // Address it and convert to pointer type (still not nil) return T(&a) } type Apple struct { color string } func example() { // Instantiating with ptr type appleFactory := FruitFactory[*Apple, Apple]{} apple := appleFactory.Create() // All good apple.color = "red" fmt.Println(apple) // &{red} }
Nota: Untuk Pendekatan 2, jenis inferens telah dilumpuhkan dalam Go 1.18, jadi anda mesti menentukan secara manual semua parameter jenis, seperti: FruitFactory[*Apple, Apple]{}.
Dengan pengubahsuaian ini, fungsi Cipta akan mengembalikan contoh jenis T (atau *T) yang sah, membolehkan anda mengakses atributnya tanpa menyebabkan kesalahan pembahagian.
Atas ialah kandungan terperinci Bagaimana untuk Mencipta Objek Bukan Nihil bagi Nilai Ditaip dalam Go 1.18 Generik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!