Mencipta Slices atau Tatasusunan daripada tidak selamat.Penunjuk di Golang: Alternatif Cekap
Penunjuk kepada tatasusunan boleh diwakili sebagai nilai uintptr dalam Golang. Walau bagaimanapun, mengakses tatasusunan asal boleh mencabar apabila penunjuk disimpan sebagai uintptr.
Kaedah Tidak Cekap: Menyalin Memori
Satu pendekatan naif ialah menyalin data daripada penunjuk ke dalam kepingan baharu:
data := make([]byte, size) stepSize := unsafe.Sizeof(data[0]) for i := 0; i < size; i++ { data[i] = *(*byte)(unsafe.Pointer(p)) p += stepSize }
Kaedah ini tidak cekap kerana melibatkan penyalinan data, yang boleh memakan masa untuk tatasusunan yang besar.
Kaedah Cekap: Reflect.SliceHeader
Pendekatan yang lebih cekap ialah menggunakan reflect.SliceHeader untuk mencipta kepingan atau tatasusunan tanpa menyalin memori:
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p sh.Len = size sh.Cap = size fmt.Println(data)
Kaedah ini menukar uintptr kepada reflect.SliceHeader dan ubah suai medannya untuk menunjuk ke tatasusunan sedia ada. Potongan atau tatasusunan yang terhasil akan berkongsi memori asas yang sama seperti tatasusunan asal.
Kaedah Alternatif: Tersurat Komposit
Alternatif lain ialah menggunakan tersurat komposit untuk mencipta reflect.SliceHeader:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
Pendekatan ini menghasilkan hasil yang sama seperti sebelumnya kaedah.
Langkah Berjaga-jaga
Apabila menggunakan penuding uintptr, adalah penting untuk memastikan tatasusunan asal kekal sah sepanjang hayat penuding. Selain itu, pakej yang tidak selamat harus digunakan dengan berhati-hati kerana potensi kesannya terhadap keselamatan jenis.
Atas ialah kandungan terperinci Bagaimana untuk Cekap Mencipta Go Slices atau Arrays daripada unsafe.Pointer?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!