Jenis Kontravarian dalam Go 1.18 Generik
Dalam Go 1.18, pengenalan generik telah mencetuskan minat terhadap jenis kontravarian. Persoalan utama yang timbul ialah cara ia berfungsi dalam konteks generik.
Tingkah Laku Tidak Serasi: Jenis Tidak Serasi
Pertimbangkan coretan kod berikut:
func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 { return func(a A) T2 { return right(left(a)) } }
Apabila cuba menggunakan Paip dengan fungsi berikut:
func OpenFile(name string) *os.File { ... } func ReadAll(rdr io.Reader) []byte { ... }
Kompilasi gagal kerana pengkompil menganggap T1 sebagai *os.Fail, yang tidak sama dengan io.Reader.
Punca Punca: Semantik Kontravarian
Isu ini berpunca daripada sifat jenis kontravarian. Dalam kes ini, T1 dijangka menjadi jenis yang lebih spesifik daripada A, bermakna fungsi yang menerima T1 juga boleh menerima A. Walau bagaimanapun, generik Go tidak menyokong jenis hasil kovarian. Oleh itu, Fungsi yang mengembalikan T1 tidak boleh mengembalikan A, walaupun ia boleh ditukar secara tersirat.
Resolusi dan Akibat
Pada masa ini tiada cara untuk mengubah suai tandatangan Pipe in Pergi 1.18 untuk membenarkan tingkah laku yang diingini. Ini tidak dianggap sebagai pepijat tetapi sebaliknya pilihan reka bentuk yang disengajakan.
Penyelesaian: Penukaran Jenis
Untuk memintas pengehadan ini, seseorang boleh menggunakan penukaran taip pada masa jalan:
func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 { return func(a A) T3 { return right(any(left(a)).(T2)) } }
Walau bagaimanapun, pendekatan ini mengorbankan keselamatan jenis masa kompilasi.
Atas ialah kandungan terperinci Bagaimana Jenis Kontravarian Berfungsi dalam Go 1.18 Generik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!