我正在寻找一种方法来将类型(可能是reflection.Type?)保存为自定义结构中的字段。这背后的原因是我将JSON数组解码为结构,我后来构建了SQL查询,但是在JSON数组中,int,浮点数和时间戳是相同的,尽管它们在查询数据库时是不同的。这意味着我需要在查询之前将每个值转换为正确的类型。
我认为答案存在于反射包中,但我还没有弄清楚如何使用它。
我希望的是这样的:
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")
有什么想法吗?
答案 0 :(得分:4)
我想你是在正确的轨道上。在Column
结构中,您正在寻找reflect.Type
。您将使用import "reflect"
获得哪些内容。
如果您的列结构包含类型名称和值(作为原始字符串),您应该能够编写打开类型的方法,并为每种情况生成正确类型的值。这里开关的简要参考; https://golang.org/doc/effective_go.html#switch
type Column struct {
Name string
DataType reflect.Type
TypedValue interface{}
StringValue string
}
因为你说"但是ints,浮点数和时间戳在JSON数组中是相同的"我假设你的json中的所有值都是技术上的字符串(意思是它们全部引用)。您可能不需要所有这些字段,但想法是将类型信息与属性名称和原始值相结合。如果您使用类型interface{}
的字段,您可以为其分配任何内容,以便您可以保存原始json数据(名称和值)以及类型信息和在此实例中的合理Go类型中的值结构很容易。
答案 1 :(得分:1)
我试图使用@evanmcdonnal提供的解决方案,但我找不到将float64
(类型json.Unmarshal
赋予任何从json数组解组的数字)转换为timestamp
的通用方法数据库中找到的任何数据类型(reflect.Value
都证明有点棘手,因为time.Time
不会将转换方法导出到timestamp
,这相当于Cassandra的typeConversion
)。
使用dataType
字段而不是json.Unmarshal
字段的工作是什么,也就是说,持有一个从type Column struct {
name string
typeConversion func(reflect.Value) reflect.Value
}
类型转换为distined列的类型的函数设置变量的类型到。
因此,我的结构看起来像这样:
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()))
}
我已经看过一些类型转换函数:
reflect.Value
这实际上恰好是一个非常好的解决方案,因为它非常通用:struct定义了应该构建任何转换函数的方式,这意味着我可以包装任何形式的转换以适应此API,并且因为返回值总是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()
来访问具有正确类型的基础值,如下所示:
keytool -keystore My1Key.keystore -list -v
答案 2 :(得分:0)
StructTag应该有所帮助:
type Table struct {
age int `sql:"type:int;`
price float `sql:"type:float;`
}