Bagaimanakah saya boleh mengisi sekeping antara muka dengan cekap dengan contoh jenis konkrit di Golang, sambil memastikan keselamatan jenis dan mengelakkan kemungkinan panik?

Patricia Arquette
Lepaskan: 2024-10-26 03:59:02
asal
213 orang telah melayarinya

How can I efficiently fill a slice of interfaces with instances of a concrete type in Golang, while ensuring type safety and avoiding potential panics?

Fungsi Isian Generik untuk Kepingan Antara Muka dan Jenis Konkrit

Di Golang, anda boleh mentakrifkan fungsi generik menggunakan generik. Apabila berurusan dengan kepingan antara muka dan jenis konkrit, tugas biasa adalah untuk memulakan semua elemen kepingan dengan jenis konkrit. Pertimbangkan fungsi berikut, yang bertujuan untuk mengisi sekeping penunjuk kepada jenis X dengan tika baharu X:

<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 dijangkakan untuk kepingan mana-mana jenis. Walau bagaimanapun, cabaran timbul apabila cuba memanjangkan tingkah laku ini kepada kepingan antara muka dan menentukan jenis konkrit untuk elemen (Y).

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

Apabila mengekang kedua-dua X dan Y kepada mana-mana, hubungan antara antara muka dan pelaksana hilang. Pengkompil menganggap X dan Y sebagai jenis yang berasingan, menghalang penetapan di antara mereka dalam badan fungsi.

Untuk menyelesaikannya, penegasan eksplisit 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, pendekatan ini mungkin panik jika Y tidak melaksanakan X, seperti dalam kes segerak.Mutex (jenis penuding) melaksanakan penyegerakan.Loker. Selain itu, memandangkan nilai sifar untuk jenis penuding adalah sifar, kaedah ini tidak memberikan peningkatan yang ketara berbanding menggunakan make([]X, n), yang turut memulakan hirisan dengan nilai sifar.

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

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

Fungsi ini mengambil parameter tambahan f, iaitu fungsi yang mengembalikan contoh X. Ini membolehkan lebih fleksibiliti dan menyokong pengisian antara muka dengan jenis konkrit. Sebagai contoh, untuk memulakan sekeping penyegerakan.Loker dengan elemen penyegerakan.Mutex, kod berikut boleh digunakan:

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

Dengan menggunakan pendekatan ini, kepingan antara muka boleh diisi secara cekap dengan contoh konkrit taip, menyediakan penyelesaian yang mudah dan selamat jenis.

Atas ialah kandungan terperinci Bagaimanakah saya boleh mengisi sekeping antara muka dengan cekap dengan contoh jenis konkrit di Golang, sambil memastikan keselamatan jenis dan mengelakkan kemungkinan panik?. 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!