éditeur php Apple vous présente la conversion de type de tranche en langage Go. Dans le langage Go, une tranche est un tableau dynamique souvent utilisé pour stocker et faire fonctionner un groupe d'éléments du même type. La conversion de type de tranche fait référence à la conversion d'un type de tranche en un autre type de tranche, ce qui est très courant dans le développement réel. Cet article présentera en détail les considérations et les applications pratiques de la conversion de type de tranche pour aider les lecteurs à mieux comprendre et utiliser cette fonctionnalité.
Je suis très nouveau, j'ai une formation en C++ et je suis tombé sur des problèmes étranges. Le code est le suivant :
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]) }
Ce code échoue avec :
runtime error: growslice: len out of range
Par exemple, si je change le casting en :
addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
Le code ci-dessus fonctionne très bien.
Je sais qu'il s'agit d'un cast vers un pointeur de tableau et que le tableau doit avoir une taille constante, Mais comment puis-je le convertir en pointeur vers une tranche ?
Pour rendre les choses encore plus confuses, il est possible d'obtenir l'adresse de la tranche et de l'attribuer à un pointeur comme ceci :
func main() { arr := []string { "one", "two", "three" } var arrPtr *[]string = &arr fmt.Println((*arrPtr)[0]) }
Tout fonctionnera bien cette fois, bien que le pointeur soit du même type que celui vers lequel j'ai lancé le pointeur dangereux dans le premier exemple. Quelqu'un peut-il m'aider à comprendre ce qui se passe exactement ici ?
Quelques informations : l'en-tête de tranche contient des pointeurs vers le tableau de support, la longueur et la capacité.
Le code dans la première partie de la question convertit l'en-tête de tranche en un pointeur vers l'en-tête de tranche. go vet
La commande prévient que le code dans la question peut abuser de unsafe.pointer.
Corrigé en supprimant l'opération de déréférencement supplémentaire afin que le code soit converti d'un pointeur vers l'en-tête de tranche en un pointeur vers l'en-tête de tranche.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer((*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
Pas besoin de convertir en *uintptr. Simplifié à :
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[]string)(unsafe.pointer(address)) fmt.println((*addptr)[0]) // prints one
Aucune farce dangereuse n'est requise. Simplifié à :
arr := []string{"one", "two", "three"} addptr := &arr fmt.println((*addptr)[0]) // prints one
Utilisez le code suivant pour convertir le pointeur de tableau de support de la tranche en pointeur de tableau. Le code est fragile car il suppose que le premier mot de l’en-tête de la tranche est un pointeur vers le tableau de sauvegarde.
arr := []string{"one", "two", "three"} address := unsafe.pointer(&arr) addptr := (*[1]string)(unsafe.pointer(*(*uintptr)(address))) fmt.println((*addptr)[0]) // prints one
La conversion uintptr dans l'extrait de code précédent n'est pas nécessaire. Simplifié à :
arr := []string{"one", "two", "three"} address := unsafe.Pointer(&arr) addPtr := (*[]string)(address) fmt.Println((*addPtr)[0]) // prints one
J'espère que cela aide.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!