繁体   English   中英

如何使用反射在结构中初始化 nil 切片

[英]How to initialize nil slices in a struct using reflect

对于任何给定的结构,我想遍历其字段并将任何 nil 切片设置为空切片。 但是,切片是不可寻址的,因此不可设置。 如何设置任何 nil 切片的值?

示例: 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))
        }
    }
}

如果您传递foo ,则无法在initNilSlices()更新/修改foo ,因为这将是一个副本,并且您只能修改副本(而不是原始值)。

这是错误消息“提示”的内容:

panic: reflect: reflect.Value.Set using unaddressable value

您从非指针值中获得了reflect.Value ,甚至reflect.ValueOf()获得的也是一个副本,因此它不允许您修改它,因为它不是您想要的。

您必须传递foo的地址:

initNilSlices(&foo)

initNilSlices()使用Value.Elem()

v := reflect.ValueOf(x).Elem()

有了它,它就可以工作并输出(在Go Playground上试试):

true
false

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM