为了账号安全,请及时绑定邮箱和手机立即绑定

如何在不使用字段名称作为字符串的情况下获取字段的标签?

如何在不使用字段名称作为字符串的情况下获取字段的标签?

Go
慕哥6287543 2023-06-26 16:46:00
是否可以使用仅接收结构和字段本身的函数来获取字段标记?我知道我可以做这样的事情:reflect.TypeOf(x).FieldByName("FieldNameAsString").Tag但在这种情况下,我不想使用字段的名称作为字符串,因为它将来可能会被重命名,所以最好使用字段本身。type MyStruct struct {    MyField string `thetag:"hello"`}func main() {    x := MyStruct{}    getTag(x, x.MyField)}
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

使用偏移量来查找字段:


// 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 ""

}

在操场上运行它

上面的代码假设垃圾收集器不会在对Pointer 的to 调用之间移动结构。这个假设在今天是正确的,但在未来可能并不正确。使用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)))

在 Playground 上运行它



查看完整回答
反对 回复 2023-06-26
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信