Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh mengisi sekeping antara muka dengan cekap dengan contoh jenis konkrit di Golang, sambil memastikan keselamatan jenis dan mengelakkan kemungkinan panik?

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
Patricia Arquetteasal
2024-10-26 03:59:02203semak imbas

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>

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>

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>

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>

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>

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!

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