Указатель на значение поля не содержит никакой информации о структуре владельца, это другой способ косвенного обращения, поэтому для решения проблемы недостаточно иметь только значение поля указателя.
Одним из решений может быть использованиеуказатель на структуру владельца вместе с указателем на поле в этой структуре, итерация полей этого значения структуры с отражением до тех пор, пока адрес итерированного поля не совпадет с указанным указателем значения поля.
https://play.golang.org/p/kaPQ9HF9wAK
package main
import (
"fmt"
"reflect"
)
func main() {
type MyStruct struct {
Foo string `tag:"val"`
}
entity := MyStruct{}
tagVal := getTag(&entity, &entity.Foo)
fmt.Println(tagVal) // val
}
func getTag(structPtr, fieldPtr interface{}) string {
sf, ok := structFieldByValPtr(structPtr, fieldPtr)
if !ok {
return ""
}
return sf.Tag.Get("tag")
}
func structFieldByValPtr(structPtr, fieldPtr interface{}) (reflect.StructField, bool) {
v := reflect.Indirect(reflect.ValueOf(structPtr))
t := v.Type()
for i := 0; i < v.NumField(); i++ {
fv := v.Field(i)
ft := t.Field(i)
if fv.Addr().Interface() == fieldPtr {
return ft, true
}
if ft.Anonymous {
sf, ok := structFieldByValPtr(fv.Addr().Interface(), fieldPtr)
if ok {
return sf, true
}
}
}
return reflect.StructField{}, false
}