Bagaimana Mengisi Slice dengan Pelaksanaan Konkrit Menggunakan Generik dan Antara Muka Golang?

Mary-Kate Olsen
Lepaskan: 2024-10-26 10:33:02
asal
712 orang telah melayarinya

How to Fill a Slice with Concrete Implementations Using Golang Generics and Interfaces?

Golang Generik: Menggabungkan Antara Muka dan Pelaksanaan Konkrit

Dalam Go 1.18, generik membenarkan pembangun mentakrifkan fungsi dan struktur data yang beroperasi pada julat jenis yang lebih luas. Walau bagaimanapun, senario khusus telah muncul di mana pengguna cuba menggunakan generik dengan antara muka sambil turut menyediakan jenis konkrit untuk parameter jenis generik.

Isu

Pertimbangkan fungsi berikut yang bertujuan untuk mengisi kepingan dengan contoh baharu jenis konkrit:

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

Fungsi ini berfungsi seperti yang diharapkan apabila mengisi sekeping penunjuk kepada jenis tertentu, seperti []*int. Walau bagaimanapun, jika kepingan terdiri daripada antara muka dan fungsi dipanggil dengan jenis konkrit untuk parameter generik, penyusunan gagal.

<code class="go">xs := make([]sync.Locker, 10) // fill with nils
Fill[sync.Locker,sync.Mutex](xs) // ouch</code>
Salin selepas log masuk

Punca

Isu timbul kerana mengekang kedua-dua jenis parameter X dan Y kepada mana-mana mengalih keluar hubungan antara antara muka dan pelaksanaan konkritnya. Pada masa penyusunan, hanya diketahui bahawa X dan Y adalah jenis yang berbeza.

Penyelesaian

Untuk menangani masalah ini, pernyataan yang jelas boleh digunakan:

<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 memperkenalkan panik masa jalan yang berpotensi jika Y tidak melaksanakan X. Selain itu, jika Y ialah jenis penuding, maklumat jenis asas hilang, mengakibatkan nilai sifar dan bukannya kejadian jenis konkrit yang diingini.

Pendekatan yang lebih baik ialah menggunakan fungsi pembina dan bukannya parameter generik kedua, seperti yang ditunjukkan di bawah:

<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

Penyelesaian ini menyediakan cara yang lebih mantap dan idiomatik untuk mengisi kepingan dengan contoh jenis konkrit tertentu manakala mengekalkan keselamatan jenis.

Atas ialah kandungan terperinci Bagaimana Mengisi Slice dengan Pelaksanaan Konkrit Menggunakan Generik dan Antara Muka 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!