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

从现有结构创建新结构时,不会在新结构上设置标签。


例如:


package main


import (

    "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?甚至可能吗?


猛跑小猪
浏览 85回答 1
1回答

MMTTMM

标签不属于实例,标签属于类型。因此,当您创建类型的新实例时,它们的类型将是相同的“佩戴”相同的标签。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上试试这个版本。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go