英文:
Parse (arbitrary) previously know data from JSON using GO
问题
我必须解析一些JSON文件。
问题是:某些字段包含的数据类型根据一些外部(已获取的)信息而变化。
我的问题是:如何使用golang来执行此操作?
我已经寻找了几个小时的解决方案,并尝试提出一个解决方案,但我始终遇到运行时错误。
此外,根据这篇帖子,我认为类型强制转换/转换应该可以工作。
对于这门语言,我是一个相当新手,所以请您在回答时不要太苛刻。
package main
import (
"encoding/json"
"fmt"
"reflect"
"unsafe"
)
func main() {
birdJson := `{
"blah": "bleh",
"coord": [[1,2], [3, 4], [22, 5]]
}
`
var result map[string]interface{}
json.Unmarshal([]byte(birdJson), &result)
fmt.Println("result:: ", result)
c := result["coord"]
cv := reflect.ValueOf(c)
ct := reflect.TypeOf(c)
fmt.Println("c value:", cv)
fmt.Println("c type: ", ct)
fmt.Println(cv.Interface().([][]int))
}
输出结果:
result:: map[blah:bleh coord:[[1 2] [3 4] [22 5]]]
c value: [[1 2] [3 4] [22 5]]
c type: []interface {}
panic: interface conversion: interface {} is []interface {}, not [][]int
goroutine 1 [running]:
main.main()
/Users/maffei/golab/t.go:27 +0x497
exit status 2
英文:
I have to parse some JSON files.
The problem is: the type of data some field contains varies according some external (already obtained) information.
My question is: how do I perform this using golang?
I've looked for a solution for this for hours and tried coming up with one, but I keep getting runtime errors.
Also, I thought the type coercion/casting would work based on this post.
I am quite a newbie regarding that language, so I ask you for not being too harsh answering this.
package main
import (
"encoding/json"
"fmt"
"reflect"
"unsafe"
)
func main() {
birdJson := `{
"blah": "bleh",
"coord" : [[1,2], [3, 4], [22, 5]]
}
`
var result map[string]interface{}
json.Unmarshal([]byte(birdJson), &result)
fmt.Println("result:: ", result)
c := result["coord"]
cv := reflect.ValueOf(c)
ct := reflect.TypeOf(c)
fmt.Println("c value:", cv)
fmt.Println("c type: ", ct)
fmt.Println(cv.Interface().([][]int))
}
The output:
result:: map[blah:bleh coord:[[1 2] [3 4] [22 5]]]
c value: [[1 2] [3 4] [22 5]]
c type: []interface {}
panic: interface conversion: interface {} is []interface {}, not [][]int
goroutine 1 [running]:
main.main()
/Users/maffei/golab/t.go:27 +0x497
exit status 2
答案1
得分: 4
这是一个示例代码,用于解析 JSON 数据。你可以按照以下方式进行解析:
package main
import (
"encoding/json"
"fmt"
)
var birdJson = []byte(`
{
"blah": "bleh",
"coord": [
[1, 2],
[3, 4],
[22, 5]
]
}
`)
func main() {
var result struct {
Blah string
Coord [][]int
}
json.Unmarshal(birdJson, &result)
fmt.Printf("%+v\n", result) // {Blah:bleh Coord:[[1 2] [3 4] [22 5]]}
}
这段代码使用了 encoding/json
包中的 Unmarshal
函数来解析 JSON 数据。首先,定义了一个结构体 result
,它包含了与 JSON 数据对应的字段。然后,通过调用 json.Unmarshal
函数将 JSON 数据解析到 result
变量中。最后,使用 fmt.Printf
函数打印解析结果。
注意:在实际使用时,你需要根据 JSON 数据的结构定义自己的结构体,并根据需要修改代码。
英文:
It's not really clear what you're trying to do, but you can Unmarshal like this:
package main
import (
"encoding/json"
"fmt"
)
var birdJson = []byte(`
{
"blah": "bleh", "coord" : [
[1,2], [3, 4], [22, 5]
]
}
`)
func main() {
var result struct {
Blah string
Coord [][]int
}
json.Unmarshal(birdJson, &result)
fmt.Printf("%+v\n", result) // {Blah:bleh Coord:[[1 2] [3 4] [22 5]]}
}
答案2
得分: 0
你不能使用单个表达式对嵌套接口进行类型断言。
如果c
的动态类型是[][]int
,那么你可以使用c.([][]int)
。
var c interface{} = [][]int{{1,2}, {3,4}}
_, ok := c.([][]int) // ok == true
然而,如果c
的动态类型是[]interface{}
,那么你需要使用c.([]interface{})
,然后需要遍历[]interface{}
切片并逐个对每个元素进行类型断言,在你的情况下,每个元素又是一个[]interface{}
,所以你还需要遍历它并对嵌套切片的每个元素进行类型断言。
另外请注意,由于JSON数字在目标类型为interface{}
时默认解组为float64
,你需要进行转换为int
以获得你想要的结果。
s1 := c.([]interface{})
out := make([][]int, len(s1))
for i := range s1 {
if s2, ok := s1[i].([]interface{}); ok {
s3 := make([]int, len(s2))
for i := range s2 {
if f64, ok := s2[i].(float64); ok {
s3[i] = int(f64) // 将float64转换为int
}
}
out[i] = s3
}
}
https://play.golang.org/p/UEdf2VSPg16
英文:
You cannot type assert nested interfaces with a single expression.
If the dynamic type of c
is [][]int
, then you can do c.([][]int)
.
var c interface{} = [][]int{{1,2}, {3,4}}
_, ok := c.([][]int) // ok == true
However, if the dynamic type of c
is []interface{}
, then you have to do c.([]interface{})
, you then have to loop over the []interface{}
slice and type assert each element individually, which, in your case, is another []interface{}
, so you'll also need to loop over that and then type assert the individual elements of the nested slice.
Also note that since JSON Numbers are by default unmarshaled as float64
when the target type is interface{}
, you'll need to do a conversion to int
to get the result you want
s1 := c.([]interface{})
out := make([][]int, len(s1))
for i := range s1 {
if s2, ok := s1[i].([]interface{}); ok {
s3 := make([]int, len(s2))
for i := range s2 {
if f64, ok := s2[i].(float64); ok {
s3[i] = int(f64) // convert float64 to int
}
}
out[i] = s3
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论