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

在 Golang 结构体字段中保存类型

在 Golang 结构体字段中保存类型

Go
幕布斯7119047 2021-10-25 18:14:21
我正在寻找一种方法来保存类型(也许是反射。类型?)作为自定义结构中的字段。这背后的原因是我将 JSON 数组解码为结构体,然后我从中构建 SQL 查询,但整数、浮点数和时间戳在 JSON 数组中是相同的,尽管它们在查询数据库时不同。这意味着我需要在查询之前将每个值转换为其正确的类型。我认为答案就在反射包的某个地方,但我还没有弄清楚如何使用它。我希望的是这样的:type Column struct {    name string    dataType type}someColumn := Column {name: "somecol", dataType: int}convertedVal := SomeConversionFunc("5", someColumn.dataType)或者,这种事情也可以工作:type Column struct {    name string    dataType func()}someColumn := Column {name: "somecol", dataType: ConvertToInt}convertedVal := someColumn.dataType("5")有任何想法吗?
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

我试图使用@evanmcdonnal 提供的解决方案,但我找不到一种通用的转换方式float64(这是json.Unmarshal从 json 数组解组的任何数字的类型)到 DB 中找到的任何数据类型(timestamp证明有点棘手,因为reflect.Value不会将转换方法导出到time.Time,这相当于 Cassandra 的timestamp)。


起作用的是使用typeConversion字段而不是dataType字段,也就是说,持有一个函数,该函数将json.Unmarshal变量的类型设置为类型转换为特定列的类型。


因此,我的结构如下所示:


type Column struct {

    name string

    typeConversion func(reflect.Value) reflect.Value

}

我已经拥有的一些 typeConversion 函数如下所示:


func floatToTime(varFloat reflect.Value) reflect.Value {

    timestamp := time.Unix(int64(varFloat.Float()), 0)

    return reflect.ValueOf(timestamp)

}


func floatToInt(varFloat reflect.Value) reflect.Value {

    return reflect.ValueOf(int(varFloat.Float()))

}

这实际上恰好是一个非常好的解决方案,因为它非常通用:结构定义了任何转换函数应该构建的方式,这意味着我可以包装任何形式的转换以适应这个 API,并且因为返回值总是reflect.Value,我可以通过调用访问具有正确类型的基础值Interface(),如下所示:


// value is the data unmarshaled by json

// I convert it to reflect.Value, then convert it again using my custom typeConversion

// Then  I use Interface() to get the final value in the final (and column-appropriate) type

column.typeConversion(reflect.ValueOf(value)).Interface()


查看完整回答
反对 回复 2021-10-25
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

该StructTag应该有所帮助:


type Table struct {

    age int `sql:"type:int;`

    price float `sql:"type:float;`

}


查看完整回答
反对 回复 2021-10-25
  • 3 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

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