editor php Apple memperkenalkan anda kepada penukaran jenis slice dalam bahasa Go. Dalam bahasa Go, slice ialah tatasusunan dinamik yang sering digunakan untuk menyimpan dan mengendalikan sekumpulan elemen daripada jenis yang sama. Penukaran jenis kepingan merujuk kepada menukar satu jenis kepingan kepada jenis kepingan lain, yang sangat biasa dalam pembangunan sebenar. Artikel ini akan memperkenalkan secara terperinci pertimbangan dan aplikasi praktikal penukaran jenis kepingan untuk membantu pembaca memahami dan menggunakan ciri ini dengan lebih baik.
Saya sangat baru pergi, mempunyai latar belakang c++ dan terjumpa beberapa isu pelik. Kodnya adalah seperti berikut:
package main import ( "fmt" "unsafe" ) func main() { arr := []string { "one", "two", "three" } address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer(*(*uintptr)(address))) fmt.println((*addptr)[0]) }
Kod ini gagal dengan:
runtime error: growslice: len out of range
Sebagai contoh, jika saya menukar pelakon kepada:
addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
Kod di atas berfungsi dengan baik.
Saya tahu ini adalah hantaran kepada penuding tatasusunan dan tatasusunan mesti mempunyai saiz yang tetap, Tetapi bagaimana saya menukarnya kepada penunjuk kepada kepingan?
Untuk menjadikan perkara lebih mengelirukan, anda boleh mendapatkan alamat hirisan dan menetapkannya kepada penunjuk seperti ini:
func main() { arr := []string { "one", "two", "three" } var arrPtr *[]string = &arr fmt.Println((*arrPtr)[0]) }
Semuanya akan berfungsi dengan baik kali ini, walaupun penunjuk adalah jenis yang sama yang saya hantarkan penunjuk tidak selamat pada contoh pertama. Bolehkah sesiapa membantu memahami apa sebenarnya yang berlaku di sini?
Sesetengah latar belakang: Pengepala kepingan mengandungi penunjuk kepada tatasusunan, panjang dan kapasiti sandaran.
Kod dalam bahagian pertama soalan menukarkan pengepala hirisan menjadi penuding kepada pengepala hirisan. go vet
Arahan memberi amaran bahawa kod dalam soalan mungkin menyalahgunakan penunjuk yang tidak selamat.
Dibetulkan dengan mengalih keluar operasi penyahrujukan tambahan supaya kod bertukar daripada penuding kepada pengepala hirisan kepada penuding kepada pengepala hirisan.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer((*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
Tidak perlu tukar ke *uintptr. Dipermudahkan kepada:
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer(address)) fmt.println((*addptr)[0]) // prints one
Tiada gurauan yang tidak selamat diperlukan. Dipermudahkan kepada:
arr := []string{"one", "two", "three"} addptr := &arr fmt.println((*addptr)[0]) // prints one
Gunakan kod berikut untuk menukar penuding tatasusunan sandaran kepingan kepada penuding tatasusunan. Kod ini rapuh kerana ia menganggap perkataan pertama pengepala hirisan ialah penunjuk kepada tatasusunan sandaran.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[1]string)(unsafe.pointer(*(*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
Penukaran uintptr dalam coretan kod sebelumnya tidak diperlukan. Dipermudahkan kepada:
arr := []string{"one", "two", "three"} address := unsafe.Pointer(&arr) addPtr := (*[]string)(address) fmt.Println((*addPtr)[0]) // prints one
Saya harap ini membantu.
Atas ialah kandungan terperinci Penukaran jenis kepingan dalam Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!