将JSON解组为最小类型
我有一个Json字符串要解组。 这是有效的:将JSON解组为最小类型,json,go,unmarshalling,Json,Go,Unmarshalling,我有一个Json字符串要解组。 这是有效的: jsonString := []byte(`{"my_int": 3, "my_string": null}`) var data map[string]interface{} err := json.Unmarshal(jsonString, &data) if err != nil { fmt.Println(err) } //avroJson := make(map[string]interface{}) for k, v :=
jsonString := []byte(`{"my_int": 3, "my_string": null}`)
var data map[string]interface{}
err := json.Unmarshal(jsonString, &data)
if err != nil {
fmt.Println(err)
}
//avroJson := make(map[string]interface{})
for k, v := range data {
fmt.Printf("%v, %T\n", k, v)
}
我的问题是:My_int
的值3返回为float64
我的问题是:如何解析具有“最小类型”的json字符串,以便3
将返回int32
,而不是最大类型3
=>float64
假设:我的Json很大,只有基本类型,我希望最小值为float64,以继续显示float64
澄清:
“最小类型”意味着如果3
可以同时考虑int32
和float64
,“最小类型”将是int32
,这正是运行此操作时得到的类型:
reflect.TypeOf(3).string()
由于您要解组到接口{}
的映射中,以下部分适用于:
要将JSON解组为接口值,解组将其中一个存储在接口值中:…
float64,用于JSON编号
字符串,用于JSON字符串
因此,要将示例数据解组为所需类型,应定义包含所需字段/类型映射的结构类型,例如:
type MyType struct {
MyInt int `json:"my_int"`
MyString *string `json:"my_string"`
}
foo := MyType{}
jsonstr := `{"my_int": 3, "my_string": null}`
err := json.Unmarshal([]byte(jsonstr), &foo)
if err != nil {
panic(err)
}
// foo => main.MyType{MyInt:3, MyString:(*string)(nil)}
由于无法在结构中描述数据,因此您可以选择:
func TransformValueTypes(o map[string]interface{}) {
for k, v := range o {
// Convert nil values to *string type.
if v == interface{}(nil) {
o[k] = (*string)(nil)
}
// Convert numbers to int32 if possible
if x, isnumber := v.(float64); isnumber {
if math.Floor(x) == x {
if x >= math.MinInt32 && x <= math.MaxInt32 {
o[k] = int32(x)
}
// Possibly check for other integer sizes here?
}
// Possibly check if float32 is possible here?
}
// Check for maps and slices here...
}
}
// my_int -> 3 (int32)
// my_string -> <nil> (*string)
// my_string2 -> "foo" (string)
// my_float -> 1.23 (float64)
当然,转换函数也可以基于键名应用类型转换逻辑
重要的是,请注意,如果您的文档可能有问题中未提及的其他结构(如嵌套对象或数组),则转换函数需要通过更多的值类型检查、递归调用和迭代来解释这些结构。定义结构。如果你解析接口{},你会直截了当地说“我不在乎类型”。你的术语“最小类型”和“最大类型”令人困惑。类型是不可比较的。。。我真的不知道这意味着什么。JSON是基于JavaScript的,在JavaScript中所有的数字都是float64,所以除非你指定一个类型,否则数字将被解码成float64。我明白你在说什么,所以让我们从更简单的开始。我想
Json.Unmarshel()
将每个值float64键入int,而不指定特定的键名。这可能吗。看看@maerics的答案和我对它的评论,他离我想做的事情越来越近了。显然,在解组后,我可以编写一个方法来完成这项工作,我正在寻找一种避免额外转换方法的方法。谢谢,但正如我在假设中提到的,我的Json文件是巨大的、动态的。我无法指定每隔几周按名称更改的100个键。我试图找出如何编写类似于您的答案的内容,而不指定特定的键,如my_int
和my_string
。有什么想法吗有没有办法通过值类型而不是键名来指定Json结构转换?这是一个很好的答案,它与我自己的实现非常相似-我使用的是结构和开关案例来为我进行检查。一个很好的解决方案是演示如何使用Json解码器,只需一次,但不声明映射键,这是我没有做到的。谢谢你的努力,值得投票表决。顺便说一句,我根据你的反馈对我的问题进行了澄清。。