Rumah >pembangunan bahagian belakang >Golang >Bagaimana untuk Mengisi Secebis Antara Muka dengan Jenis Konkrit dalam Generik Golang?

Bagaimana untuk Mengisi Secebis Antara Muka dengan Jenis Konkrit dalam Generik Golang?

Barbara Streisand
Barbara Streisandasal
2024-10-26 05:38:30535semak imbas

How to Fill a Slice of Interfaces with Concrete Types in Golang Generics?

Golang Generik: Menggunakan Antara Muka dan Jenis Konkrit Secara serentak

Dalam Go 1.18, generik telah memperkenalkan kemungkinan baharu untuk pengendalian jenis. Walau bagaimanapun, senario tertentu mungkin menimbulkan cabaran apabila menggunakan antara muka dan jenis konkrit bersama-sama.

Satu senario sedemikian timbul apabila cuba mencipta fungsi seperti ini:

<code class="go">func Fill[X any](slice []*X){
   for i := range slice {
      slice[i] = new(X)
   }
}</code>

Fungsi ini bertujuan untuk mengisi kepingan antara muka dengan jenis konkrit. Sebagai contoh, tatasusunan *int boleh diisi dengan new(int) menggunakan fungsi ini.

Isu timbul apabila cuba mengisi sekeping antara muka dengan jenis konkrit yang melaksanakan antara muka. Pertimbangkan kod ini:

<code class="go">func Fill[X, Y any](slice []X){
   for i := range slice {
      slice[i] = new(Y) // not work!
   }
}

xs := make([]sync.Locker, 10) // fill with nils
Fill[sync.Locker,sync.Mutex](xs) // ouch</code>

Dalam kes ini, fungsi tidak berfungsi kerana mengekang kedua-dua X dan Y kepada mana-mana memutuskan hubungan antara antara muka dan jenis pelaksana. Pengkompil hanya menyedari bahawa X dan Y adalah jenis yang berbeza pada masa penyusunan.

Penyelesaian Yang Mungkin

Terdapat penyelesaian untuk membuat kod dikompilasi menggunakan penegasan eksplisit:

<code class="go">func Fill[X, Y any](slice []X) {
    for i := range slice {
        slice[i] = any(*new(Y)).(X)
    }
}</code>

Walau bagaimanapun, penyelesaian ini mempunyai kelemahan yang ketara: ia panik jika Y tidak melaksanakan X, seperti dengan penyegerakan.Loker dan penyegerakan.Mutex. Selain itu, menggunakan jenis penuding untuk Y menghasilkan nilai sifar kerana ia kehilangan jenis asas dan maklumat nilai sifar.

Alternatif yang Lebih Baik

Penyelesaian yang lebih mantap ialah menggunakan fungsi pembina dan bukannya parameter jenis kedua:

<code class="go">func main() {
    xs := make([]sync.Locker, 10)
    Fill(xs, func() sync.Locker { return &sync.Mutex{} })
}

func Fill[X any](slice []X, f func() X) {
    for i := range slice {
        slice[i] = f()
    }
}</code>

Dalam pendekatan ini, fungsi mengambil kepingan jenis X dan fungsi pembina. Fungsi pembina mencipta tika jenis X, mengisi kepingan dengan tika konkrit.

Atas ialah kandungan terperinci Bagaimana untuk Mengisi Secebis Antara Muka dengan Jenis Konkrit dalam Generik Golang?. 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