为了账号安全,请及时绑定邮箱和手机立即绑定

使用reflect.New时如何设置标签

使用reflect.New时如何设置标签

Go
猛跑小猪 2022-05-18 13:37:30
从现有结构创建新结构时,不会在新结构上设置标签。例如:package mainimport (    "fmt"    "reflect")type Foo struct {  Bar string `custom:"tag"`}func readTag(e interface{}) {  t := reflect.TypeOf(e).Elem()  f, _ := t.FieldByName("Bar")  fmt.Println(f.Tag)}func main() {  foo := &Foo{"baz"}  fmt.Println(foo)  readTag(foo)  fooType := reflect.TypeOf(foo).Elem()  newFoo := reflect.New(fooType).Elem()  newFoo.FieldByName("Bar").SetString("baz2")  fmt.Println(newFoo)  readTag(&newFoo)// empty}游乐场链接: https: //play.golang.org/p/7-zMPnwQ8Vo使用时如何设置标签reflect.New?甚至可能吗?
查看完整描述

1 回答

?
MMTTMM

TA贡献1869条经验 获得超4个赞

标签不属于实例,标签属于类型。


因此,当您创建类型的新实例时,它们的类型将是相同的“佩戴”相同的标签。reflect使用文字或通过包创建新实例都没有关系。


您的问题newFoo是 type reflect.Value,并且&newFoo是 type *reflect.Value,它不是指向您的 struct 的指针(不是 type *Foo)。


如果解开结构值:


newFoo.Interface()

然后你通过它,你使Elem()调用成为可选的(只有当它是一个指针时才这样做):


func readTag(e interface{}) {

    t := reflect.TypeOf(e)

    if t.Kind() == reflect.Ptr {

        t = t.Elem()

    }

    f, _ := t.FieldByName("Bar")

    fmt.Println(f.Tag)

}

然后你会得到相同的标签(在Go Playground上试试):


&{baz}

custom:"tag"

{baz2}

custom:"tag"

如果你保持reflect.Value包装结构指针,你会得到相同的结果,并从中解开:


newFooPtr := reflect.New(fooType)

newFoo := newFooPtr.Elem()

newFoo.FieldByName("Bar").SetString("baz2")

fmt.Println(newFoo)

readTag(newFooPtr.Interface()) // empty

那么readTag()就不需要修改了。在Go Playground上试试这个版本。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信