Используйте смещения, чтобы найти поле:
// getTag returns the tag for a field given a pointer to
// a struct and a pointer to the field in that struct.
func getTag(pv interface{}, pf interface{}) reflect.StructTag {
v := reflect.ValueOf(pv)
offset := reflect.ValueOf(pf).Pointer() - v.Pointer()
t := v.Type().Elem()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Offset == offset {
return f.Tag
}
}
return ""
}
Запустите его на детской площадке .
В приведенном выше коде предполагается, что сборщик мусора не перемещает структуру между вызовами to в Pointer . Это предположение верно сегодня, но может не соответствовать действительности в будущем. Используйте пакет unsafe , чтобы защитить код от будущих изменений в сборщике мусора:
// getTag returns the tag for a field with the given offset
// in the struct pointed to by pv.
func getTag(pv interface{}, offset uintptr) reflect.StructTag {
t := reflect.TypeOf(pv).Elem()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
if f.Offset == offset {
return f.Tag
}
}
return ""
}
Назовите это так:
x := MyStruct{}
fmt.Println(getTag(&x, unsafe.Offsetof(x.MyField)))
Запустите его на игровой площадке .