Поиск тега по символу поля в Go - PullRequest
1 голос
/ 09 ноября 2019

Учитывая структуру с полями, я бы хотел символически найти значение тега для определенного поля (без указания имени поля в виде строки).

type MyStruct struct {
    Foo string `tag:"val"`
}
entity := MyStruct{}
tagVal := getTag(&entity.Foo) // the function would return "val" for Foo field

Я бы хотел реализовать функцию getTag, котораявернет значение тега для данного поля.

1 Ответ

0 голосов
/ 09 ноября 2019

Указатель на значение поля не содержит никакой информации о структуре владельца, это другой способ косвенного обращения, поэтому для решения проблемы недостаточно иметь только значение поля указателя.

Одним из решений может быть использованиеуказатель на структуру владельца вместе с указателем на поле в этой структуре, итерация полей этого значения структуры с отражением до тех пор, пока адрес итерированного поля не совпадет с указанным указателем значения поля.

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...