Rumah >pembangunan bahagian belakang >Golang >Mengapa Fungsi `Paip` Gagal Disusun dengan Jenis Serasi dalam Go 1.18 Generik?

Mengapa Fungsi `Paip` Gagal Disusun dengan Jenis Serasi dalam Go 1.18 Generik?

DDD
DDDasal
2024-11-17 10:30:04504semak imbas

Why Does the `Pipe` Function Fail to Compile with Compatible Types in Go 1.18 Generics?

Gelagat Jenis Kontravarian dalam Go 1.18 Generik

Go 1.18 memperkenalkan generik, yang membolehkan penciptaan kod selamat jenis. Walau bagaimanapun, tingkah laku tertentu mungkin berbeza daripada jangkaan, seperti dengan jenis kontravarian.

Pertimbangkan fungsi berikut dalam Go 1.18:

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))
    }
}

Fungsi ini direka bentuk untuk memaipkan output kiri sebagai input ke kanan. Walau bagaimanapun, ia gagal untuk menyusun apabila digunakan seperti berikut:

func OpenFile(name string) *os.File {
    ...
}

func ReadAll(rdr io.Reader) []byte {
    ...
}

var OpenRead = Pipe(OpenFile, ReadAll)

Ini kerana pengkompil menentukan bahawa T1 ialah *os.Fail, yang tidak sama dengan io.Reader walaupun ia serasi.

Tingkah laku yang diingini ialah keupayaan untuk merantai fungsi Paip dengan fungsi yang menerima jenis yang serasi sebagai input. Ini sejajar dengan gelagat yang dijangkakan apabila menggunakan rantai tanpa generik.

Soalan:

  1. Adakah terdapat cara untuk melaraskan tandatangan Paip untuk membolehkan tingkah laku yang diingini?
  2. Adakah tingkah laku ini melalui reka bentuk atau pepijat?

Jawapan:

  1. Tidak, pada masa ini tiada cara untuk menyatakan keserasian antara jenis menggunakan generik dalam Go 1.18.
  2. Tingkah laku ini bukan pepijat. Ia mencerminkan kekurangan sokongan untuk jenis hasil kovarian dalam Go.

Penyelesaian:

Walaupun tidak mungkin untuk mencapai "compile-time type-safe " tingkah laku, satu penyelesaian yang mungkin adalah dengan menggunakan penegasan jenis:

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))
    }
}

Kod ini tidak selamat jenis pada masa penyusunan, tetapi ia mungkin memberikan kefungsian yang diingini dalam beberapa kes.

Atas ialah kandungan terperinci Mengapa Fungsi `Paip` Gagal Disusun dengan Jenis Serasi dalam Go 1.18 Generik?. 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