如何在使用 reflect.New 时设置标签
How to set tags while using 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
}
游乐场link:https://play.golang.org/p/7-zMPnwQ8Vo
使用reflect.New
时如何设置标签?有可能吗?
标签不属于实例,标签属于类型。
因此,当您创建类型的新实例时,它们的类型将与 "wearing" 相同的标签相同。使用文字或通过 reflect
包创建新实例并不重要。
你的问题是 newFoo
是 reflect.Value
类型,&newFoo
是 *reflect.Value
类型,它不是指向你的结构的指针(不是类型 *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.
上试用此版本
从现有结构创建新结构时,不会在新结构上设置标签。
例如:
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
}
游乐场link:https://play.golang.org/p/7-zMPnwQ8Vo
使用reflect.New
时如何设置标签?有可能吗?
标签不属于实例,标签属于类型。
因此,当您创建类型的新实例时,它们的类型将与 "wearing" 相同的标签相同。使用文字或通过 reflect
包创建新实例并不重要。
你的问题是 newFoo
是 reflect.Value
类型,&newFoo
是 *reflect.Value
类型,它不是指向你的结构的指针(不是类型 *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.