在Golang结构域中保存一个类型

时间:2015-07-29 16:10:46

标签: reflection struct go

我正在寻找一种方法来将类型(可能是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")

有什么想法吗?

3 个答案:

答案 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;`
}