Maison >développement back-end >Golang >Comment créer efficacement un Go Array ou une Slice à partir d'un unsafe.Pointer ?

Comment créer efficacement un Go Array ou une Slice à partir d'un unsafe.Pointer ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-11 02:25:16702parcourir

How to Efficiently Create a Go Array or Slice from an unsafe.Pointer?

Comment initialiser efficacement un tableau ou une tranche d'un tableau dangereux.Pointeur dans Go

Dans le monde de Go, vous pouvez rencontrer des scénarios où vous devez travailler avec des structures de données représentées comme unsafe.Pointer. Par exemple, vous pourriez avoir un pointeur vers un tableau comme :

p := uintptr(unsafe.Pointer(&array))
size := 5

Cependant, accéder directement au tableau n'est pas possible, car le pointeur est simplement une représentation de son adresse. Cela vous laisse face au défi de créer un tableau ou une tranche en utilisant le pointeur, la taille et le type de données connus sans recourir à des copies de mémoire.

Approche dangereuse de la création d'un tableau/tranche

Dans un premier temps, vous pouvez envisager l'approche suivante :

data := make([]byte, size)
stepSize := unsafe.Sizeof(data[0])
for i := 0; i < size; i++ {
    data[i] = *(*byte)(unsafe.Pointer(p))
    p += stepSize
}

Cette solution copie les données du tableau d'origine vers la nouvelle tranche, qui peut être inefficace, en particulier pour les grands ensembles de données.

Approche efficace utilisant Reflect.SliceHeader

Une alternative plus efficace consiste à exploiter la puissance du package de réflexion de Go et de Reflect.SliceHeader taper. En manipulant directement les champs de réflexion.SliceHeader, vous pouvez créer un tableau ou une tranche qui référence les mêmes données sous-jacentes que votre pointeur.

Étape 1 : Obtenir le descripteur de réflexion.SliceHeader

Déclarez une variable slice et convertissez son type []byte en *reflect.SliceHeader en utilisant unsafe conversions :

var data []byte
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))

Étape 2 : Modifier les champs SliceHeader

Attribuez le pointeur, la taille et éventuellement la capacité aux champs de réflexion.SliceHeader :

sh.Data = p
sh.Len = size
sh.Cap = size

Étape 3 : Reconvertir aux données d'origine tapez

Enfin, convertissez le reflet modifié.SliceHeader vers le type de données souhaité en utilisant des conversions non sécurisées :

data = *(*[]byte)(unsafe.Pointer(sh))

Cette approche efficace vous permet de créer un tableau ou une tranche qui partage les mêmes données sous-jacentes que votre pointeur sans encourir le coût de copies de mémoire inutiles.

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!

Déclaration:
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