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

Barbara Streisand
Lepaskan: 2024-10-26 05:38:30
asal
368 orang telah melayarinya

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!