In Go, using reflect.MakeSlice to create a slice returns an un-addressable Value. This becomes an issue when a slice address is required, as demonstrated in the following code snippet:
collection.Find(bson.M{}).All(&result)
To resolve this issue, there are two solutions:
1. Using reflect.New()
The simplest solution is to use reflect.New() to create a pointer. For example:
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())
2. Using a Typed Map
Alternatively, you can use a typed map to create a slice of the desired type:
type MyStructList map[string]*MyStruct myMap := reflect.New(reflect.MapOf(myKey, myValue)) for _, value := range myMap.MapKeys() { myValue := myMap.MapIndex(value) }
Local stack variables, including those created by reflect.MakeSlice, are not addressable in Go. This ensures that pointers to these variables remain meaningful and do not point to invalid memory locations.
The mgo API requires a pointer to a slice for its iter.All function because appending to a slice may reallocate memory. To communicate these changes to the caller, a pointer is necessary.
The above is the detailed content of Why Does `reflect.MakeSlice` Return an Un-addressable Value in Go?. For more information, please follow other related articles on the PHP Chinese website!