Maison > développement back-end > Golang > Conversion de type de tranche dans Go

Conversion de type de tranche dans Go

WBOY
Libérer: 2024-02-10 15:00:20
avant
633 Les gens l'ont consulté

Go 中的切片类型转换

é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é.

Contenu de la question

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])
}
Copier après la connexion

Ce code échoue avec :

runtime error: growslice: len out of range
Copier après la connexion

Par exemple, si je change le casting en :

addptr := (*[0]string)(unsafe.pointer(*(*uintptr)(address)))
Copier après la connexion

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])
}
Copier après la connexion

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 ?

Solution de contournement

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
Copier après la connexion

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
Copier après la connexion

Aucune farce dangereuse n'est requise. Simplifié à :

arr := []string{"one", "two", "three"}
addptr := &arr
fmt.println((*addptr)[0]) // prints one
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal