php小編蘋果為大家介紹Go語言中的切片型別轉換。在Go語言中,切片是一種動態數組,常用於儲存和操作一組相同類型的元素。切片類型轉換是指將一個類型的切片轉換為另一個類型的切片,這在實際開發中非常常見。本文將詳細介紹切片類型轉換的注意事項和實際應用,幫助讀者更能理解並運用這項特性。
我對 go 很陌生,有 c 背景,並且偶然發現了一些奇怪的問題。 程式碼如下:
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]) }
此程式碼失敗並顯示:
runtime error: growslice: len out of range
例如,如果我將演員表更改為:
addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
上面的程式碼工作得很好。
我知道這是對陣列指標的強制轉換,並且陣列必須具有恆定的大小, 但如何將其轉換為指向切片的指標呢?
更令人困惑的是,可以取得切片位址並將其指派給指針,如下所示:
func main() { arr := []string { "one", "two", "three" } var arrPtr *[]string = &arr fmt.Println((*arrPtr)[0]) }
這次一切都會正常,儘管指標的類型與我在第一個範例中將不安全指標轉換為相同的類型。 有人可以幫忙理解這裡到底發生了什麼事嗎?
一些背景:切片標頭包含指向後備數組、長度和容量的指標。
問題第一部分中的程式碼將切片頭轉換為指向切片頭的指標。 go vet
指令警告問題中的程式碼可能濫用 unsafe.pointer。
透過刪除額外的取消引用操作來修復,以便程式碼從指向切片頭的指標轉換為指向切片頭的指標。
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer((*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
不需要轉換為 *uintptr。簡化為:
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer(address)) fmt.println((*addptr)[0]) // prints one
不需要不安全的惡作劇。簡化為:
arr := []string{"one", "two", "three"} addptr := &arr fmt.println((*addptr)[0]) // prints one
使用下列程式碼將切片的後備陣列指標轉換為陣列指標。程式碼很脆弱,因為它假設切片頭的第一個字是指向後備數組的指標。
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[1]string)(unsafe.pointer(*(*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
不需要前面程式碼片段中的 uintptr 轉換。簡化為:
arr := []string{"one", "two", "three"} address := unsafe.Pointer(&arr) addPtr := (*[]string)(address) fmt.Println((*addPtr)[0]) // prints one
我希望這會有所幫助。
以上是Go 中的切片類型轉換的詳細內容。更多資訊請關注PHP中文網其他相關文章!