Mencipta Tatasusunan atau Slice daripada Penuding Tatasusunan di Golang
Di Golang, mencipta tatasusunan atau hirisan daripada penuding tatasusunan menggunakan tidak selamat. Penunjuk boleh mencabar kerana salinan memori yang ditanggung oleh kaedah tradisional seperti memcpy atau reflect.SliceHeader. Untuk menangani isu ini, kami membincangkan pendekatan alternatif.
Kata Pengantar:
Sebelum menyelidiki penyelesaian, adalah penting untuk ambil perhatian bahawa menggunakan nilai uintptr tidak menghalang tatasusunan asal daripada menjadi sampah yang dikutip. Oleh itu, adalah penting untuk berhati-hati semasa mengendalikan nilai tersebut, memastikan kesahihannya sebelum mengaksesnya. Selain itu, amat disyorkan untuk mengehadkan penggunaan pakej yang tidak selamat, mengutamakan mekanisme keselamatan jenis Go.
Penyelesaian Menggunakan reflect.SliceHeader:
Satu kaedah berkesan melibatkan memanipulasi pantulan .SliceHeader deskriptor pembolehubah hirisan untuk menunjuk ke tatasusunan yang dikehendaki. Ini melibatkan pengubahsuaian medan Data, Len dan Capnya.
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p // Pointer to the array sh.Len = size sh.Cap = size fmt.Println(data)
Dengan melakukan pengubahsuaian ini, pembolehubah kepingan data secara berkesan menghala ke tatasusunan yang sama seperti penuding awal.
Penyelesaian Alternatif Menggunakan Literal Komposit:
Pendekatan lain ialah membuat refleksi.SliceHeader menggunakan literal komposit, kemudian tukarkannya kepada kepingan:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
Kaedah ini menghasilkan hasil yang sama seperti penyelesaian sebelumnya.
Kaveat dan Amaran:
Penyelesaian yang disebutkan di atas bergantung pada andaian bahawa tatasusunan asal tidak akan dikumpul sampah semasa penunjuk sedang digunakan. Adalah penting untuk memastikan bahawa pembekal penunjuk menjamin kesahihannya.
Selain itu, dokumentasi untuk tidak selamat.Penunjuk secara jelas memberi amaran terhadap pengisytiharan atau memperuntukkan pembolehubah reflect.SliceHeader jenis struktur secara langsung. Sebaliknya, ia hanya boleh digunakan sebagai penunjuk yang menunjuk kepada kepingan atau rentetan sebenar.
Atas ialah kandungan terperinci Bagaimana untuk Mencipta Go Slice dengan Selamat daripada Penunjuk Tatasusunan Tanpa Menyalin Memori?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!