Maison >développement back-end >Golang >Pourquoi « reflect.MakeSlice » renvoie-t-il une « valeur » non adressable ?

Pourquoi « reflect.MakeSlice » renvoie-t-il une « valeur » non adressable ?

Barbara Streisand
Barbara Streisandoriginal
2024-11-08 05:36:011094parcourir

Why does `reflect.MakeSlice` return an un-addressable `Value`?

Pourquoi golang réfléchit-il.MakeSlice renvoie-t-il une valeur non adressable ?

Cette question découle de la nécessité de créer une adresse de tranche à utiliser dans une fonction qui accepte un pointeur vers une tranche.

Pourquoi reflex.MakeSlice renvoie-t-il une valeur non adressable ?

Une valeur lâche La définition de l'adressabilité dans Go est que vous pouvez prendre l'adresse de quelque chose et être assuré que cette adresse pointe vers un endroit significatif. Si vous allouez quelque chose sur la pile dans le corps d'une fonction, l'adresse de la valeur allouée ne sera plus accessible à un moment donné. Par conséquent, cette valeur n'est pas adressable.

Dans la plupart des cas, Go déplace les variables de pile locales vers le tas si elles sont renvoyées ou autrement promues vers l'extérieur, mais au moment de l'exécution, cela n'est pas fait. Par conséquent, CanAddr() ne renvoie true que lorsque :

  A value is addressable if it is an element of a slice, an element of an addressable array, a field of an addressable struct, or the result of dereferencing a pointer.

Les types indiqués ont tous une chose en commun : ils garantissent que ce qu'ils contiennent sera accessible de partout et pointent vers une valeur significative en mémoire. Vous n'avez ni élément slice, ni pointeur, ni aucun des autres éléments mentionnés depuis que vous avez créé une tranche locale à l'aide de Reflect.MakeSlice. Les éléments de ladite tranche seraient cependant adressables (puisque la mémoire de la tranche réside sur le tas).

Comment obtenir un pointeur vers une tranche en utilisant la réflexion

La solution la plus simple est probablement d'utiliser la réflexion .New() pour créer le pointeur (exemple complet sur play) :

my := &My{}

// Create a slice to begin with
myType := reflect.TypeOf(my)
slice := reflect.MakeSlice(reflect.SliceOf(myType), 10, 10)

// Create a pointer to a slice value and set it to the slice
x := reflect.New(slice.Type())
x.Elem().Set(slice)

collection.Find(bson.M{}).All(x.Interface())

Notez le x.Interface() qui a également été signalé par d'autres réponses. Cela évite qu'au lieu de la réflexion.Value, la valeur réelle de x soit transmise à All().

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