Heim >Backend-Entwicklung >Golang >Konvertierung des Slice-Typs in Go
php-Editor Apple führt Sie in die Slice-Typ-Konvertierung in der Go-Sprache ein. In der Go-Sprache ist ein Slice ein dynamisches Array, das häufig zum Speichern und Betreiben einer Gruppe von Elementen desselben Typs verwendet wird. Unter Slice-Typkonvertierung versteht man die Konvertierung eines Slice-Typs in einen anderen Slice-Typ, was in der tatsächlichen Entwicklung sehr häufig vorkommt. In diesem Artikel werden die Überlegungen und praktischen Anwendungen der Slice-Typ-Konvertierung ausführlich vorgestellt, um den Lesern zu helfen, diese Funktion besser zu verstehen und zu verwenden.
Ich bin ganz neu, habe einen C++-Hintergrund und bin auf einige seltsame Probleme gestoßen. Der Code lautet wie folgt:
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]) }
Dieser Code schlägt fehl mit:
runtime error: growslice: len out of range
Zum Beispiel, wenn ich die Besetzung ändere in:
addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
Der obige Code funktioniert einwandfrei.
Ich weiß, dass dies eine Umwandlung in einen Array-Zeiger ist und das Array eine konstante Größe haben muss. Aber wie konvertiere ich es in einen Zeiger auf ein Slice?
Um die Sache noch verwirrender zu machen, ist es möglich, die Slice-Adresse abzurufen und sie einem Zeiger wie diesem zuzuweisen:
func main() { arr := []string { "one", "two", "three" } var arrPtr *[]string = &arr fmt.Println((*arrPtr)[0]) }
Dieses Mal wird alles gut funktionieren, obwohl der Zeiger vom gleichen Typ ist, auf den ich im ersten Beispiel den unsicheren Zeiger umgewandelt habe. Kann jemand helfen zu verstehen, was genau hier vor sich geht?
Einige Hintergrundinformationen: Der Slice-Header enthält Zeiger auf das Hintergrundarray, die Länge und die Kapazität.
Der Code im ersten Teil der Frage wandelt den Slice-Header in einen Zeiger auf den Slice-Header um. go vet
Der Befehl warnt, dass der Code in der Frage möglicherweise unsafe.pointer missbraucht.
Behoben durch Entfernen der zusätzlichen Dereferenzierungsoperation, sodass der Code von einem Zeiger auf den Slice-Header in einen Zeiger auf den Slice-Header konvertiert wird.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer((*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
Keine Konvertierung in *uintptr erforderlich. Vereinfacht zu:
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer(address)) fmt.println((*addptr)[0]) // prints one
Keine unsicheren Streiche erforderlich. Vereinfacht zu:
arr := []string{"one", "two", "three"} addptr := &arr fmt.println((*addptr)[0]) // prints one
Verwenden Sie den folgenden Code, um den Backing-Array-Zeiger des Slice in einen Array-Zeiger umzuwandeln. Der Code ist fragil, da er davon ausgeht, dass das erste Wort des Slice-Headers ein Zeiger auf das Hintergrundarray ist.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[1]string)(unsafe.pointer(*(*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
Die uintptr-Konvertierung im vorherigen Code-Snippet ist nicht erforderlich. Vereinfacht zu:
arr := []string{"one", "two", "three"} address := unsafe.Pointer(&arr) addPtr := (*[]string)(address) fmt.Println((*addPtr)[0]) // prints one
Ich hoffe, das hilft.
Das obige ist der detaillierte Inhalt vonKonvertierung des Slice-Typs in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!