For any given struct, I want to loop over its fields and set any nil slices to an empty slice. However, slices are unaddressable and hence not settable. How can I set the values of any nil slices?
Example: https://goplay.space/#iV6OHkYVTru
package main
import (
"fmt"
"reflect"
)
type Foo struct {
IntSlice []int
StrSlice []string
}
func main() {
foo := Foo{}
fmt.Println(foo.IntSlice == nil)
initNilSlices(foo)
fmt.Println(foo.IntSlice == nil)
}
func initNilSlices(x interface{}) {
v := reflect.ValueOf(x)
for i := 0; i < v.NumField(); i++ {
f := v.Field(i)
if f.Kind() == reflect.Slice {
t := f.Type()
f.Set(reflect.MakeSlice(t, 0, 0))
}
}
}
You can't update / modify foo
in initNilSlices()
if you pass foo
because that will be a copy, and you could only modify the copy (and not the original value).
This is what the error message "hints":
panic: reflect: reflect.Value.Set using unaddressable value
You obtained the reflect.Value
from a non-pointer value, and even what reflect.ValueOf()
gets is a copy, so it doesn't allow you to modify it because it wouldn't be what you'd want.
You have to pass the address of foo
:
initNilSlices(&foo)
And in initNilSlices()
use Value.Elem()
:
v := reflect.ValueOf(x).Elem()
With this it works and outputs (try it on the Go Playground ):
true
false
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.