反射获取字段标签

Reflection to get field tag

在 Go 中,有没有一种使用反射来获取字段标记的好方法,只需将字段包装在反射库中的函数中?

我基本上是在尝试创建一个瘦数据访问对象,它允许在数据库中获取列名,而无需在整个地方进行硬编码。

下面是将数据库列名称作为标签的结构。

    // Table Structures
type CusipTableRow struct {
    Id          int64  `db:"id"`
    Cusip       string `db:"cusip"`
    Symbol      string `db:"symbol"`
    Active      int8   `db:"active"`
    Added_Time  int32  `db:"added_timestamp"`
    Description string `db:"description"`
    Exchange    string `db:"exchange"`
    AssetType   string `db:"asset_type"`
}

我正在寻求一个建议,而不是下载另一个关于如何使用反射来本质上对 return 具有标签值的字符串进行这样的调用的库。

var row CusipTableRow
row.GetColumnName(row.Id) //Return column name based on tag.

我正在考虑可能尝试使用 map[address] fieldTag,但由于没有完全掌握 unsafe 包,所以没能成功。如果这种方法行得通,我认为这样的调用可能行得通:

row.GetColumnName(&row.Id) //Return column name based on tag.

您可以根据结构体的地址和字段的地址获取字段标签。不需要不安全的恶作剧。

func GetColumnName(pstruct interface{}, pfield interface{}) string {
    v := reflect.ValueOf(pstruct).Elem()
    for i := 0; i < v.NumField(); i++ {
        if v.Field(i).Addr().Interface() == pfield {
            return v.Type().Field(i).Tag.Get("db")
        }
    }
    panic("field not in struct")
}

使用示例:

var v CusipTableRow
fmt.Println(GetColumnName(&v, &v.Added_Time)) // prints added_timestamp

Run it on the Go Playground.