Теги не принадлежат экземплярам, теги принадлежат типам.
Таким образом, когда вы создаете новые экземпляры вашего типа, их тип будет одинаково «носить» одинаковые теги. Не имеет значения, создаете ли вы новые экземпляры с литералами или через пакет 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 .