检查 IsZero 时使用反射恐慌按名称获取字段

我有一段反射代码尝试按名称获取结构上的字段,然后检查该字段是否存在:


type test struct {

   A bool

   B bool

}


t := new(test)

metaValue := reflect.ValueOf(t).Elem()

field := metaValue.FieldByName(name)

if field.IsZero() {

    glog.Errorf("Field %s was not on the struct", inner)

}

根据 上的文档FieldByName,如果未找到任何字段,此函数应返回零值。但是,下一行会出现以下错误:


panic: reflect: call of reflect.Value.IsZero on zero Value


goroutine 268 [running]:

reflect.Value.IsZero({0x0, 0x0, 0x112a974})

        reflect/value.go:1475 +0x27f

根据这个 GitHub 问题,只有当值包含 nil (即没有类型)时才会发生这种情况,并且IsValid应该使用它。为什么会这样?


RISEBY
浏览 78回答 1
1回答

神不在的星期二

Value.IsZero()报告包装的值是否是其类型的零值。这与reflect.Value自身为零(reflect.Value其零值是结构)不同。另请注意,t在您的代码中不是结构值,它是指向结构的指针。用于Value.Elem()导航到包装的结构值(或不从指针开始)。如果该字段不存在,Value.FieldByName()则返回 的零值reflect.Value,而不是reflect.Value持有某种类型的零值的非零值;如果找不到字段,则没有类型信息。因此,要检查该字段是否不存在,请reflect.Value通过将其与以下内容进行比较来检查其本身是否为零reflect.Value{}:if field == (reflect.Value{}) {    log.Printf("Field %s was not on the struct", name)}测试它:type test struct {    A bool    B bool    x bool}v := new(test)metaValue := reflect.ValueOf(v).Elem()for _, name := range []string{"A", "x", "y"} {    field := metaValue.FieldByName(name)    if field == (reflect.Value{}) {        log.Printf("Field %s was not on the struct", name)    }}这将输出(在Go Playground上尝试):2009/11/10 23:00:00 Field y was not on the struct
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go