Penukaran jenis kepingan dalam Go

WBOY
Lepaskan: 2024-02-10 15:00:20
ke hadapan
578 orang telah melayarinya

Go 中的切片类型转换

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.

Kandungan soalan

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])
}
Salin selepas log masuk

Kod ini gagal dengan:

runtime error: growslice: len out of range
Salin selepas log masuk

Sebagai contoh, jika saya menukar pelakon kepada:

addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
Salin selepas log masuk

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])
}
Salin selepas log masuk

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?

Penyelesaian

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
Salin selepas log masuk

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
Salin selepas log masuk

Tiada gurauan yang tidak selamat diperlukan. Dipermudahkan kepada:

arr := []string{"one", "two", "three"}
addptr := &arr
fmt.println((*addptr)[0]) // prints one
Salin selepas log masuk

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
Salin selepas log masuk

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
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
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
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!