假设我有一个应用程序以两种不同的格式接收json数据。
f1 = `{"pointtype":"type1", "data":{"col1":"val1", "col2":"val2"}}`
f2 = `{"pointtype":"type2", "data":{"col3":"val3", "col3":"val3"}}`
我有一个与每种类型相关联的结构:
type F1 struct {
col1 string
col2 string
}
type F2 struct {
col3 string
col4 string
}
假设我使用encoding/json
库将原始json数据转换为struct:
类型Point {
pointtype字符串
数据json.RawMessage
}
如何通过了解点类型将数据解码为适当的结构?
我正在尝试以下方面:
func getType(pointType string) interface{} {
switch pointType {
case "f1":
var p F1
return &p
case "f2":
var p F2
return &p
}
return nil
}
哪个不起作用,因为返回的值是接口,而不是正确的struct类型。 如何使这种开关结构选择工作?
答案 0 :(得分:5)
您可以在方法返回的界面上type switch:
switch ps := parsedStruct.(type) {
case *F1:
log.Println(ps.Col1)
case *F2:
log.Println(ps.Col3)
}
...等。请记住,要使encoding/json
包正确解码(通过反射),您的字段需要导出(大写第一个字母)。
答案 1 :(得分:1)
另一种方法是使用地图(由原生json包支持)。
这里我假设每个数据属性(col1,col2 ...)都存在,但是map允许你检查它。
package main
import "fmt"
import "encoding/json"
type myData struct {
Pointtype string
Data map[string]string
}
func (d *myData) PrintData() {
if d.Pointtype == "type1" {
fmt.Printf("type1 with: col1 = %v, col2 = %v\n", d.Data["col1"], d.Data["col2"])
} else if d.Pointtype == "type2" {
fmt.Printf("type2 with: col3 = %v, col4 = %v\n", d.Data["col3"], d.Data["col4"])
} else {
fmt.Printf("Unknown type: %v\n", d.Pointtype)
}
}
func main() {
f1 := `{"pointtype":"type1", "data":{"col1":"val1", "col2":"val2"}}`
f2 := `{"pointtype":"type2", "data":{"col3":"val3", "col4":"val4"}}`
var d1 myData
var d2 myData
json.Unmarshal([]byte(f1), &d1)
json.Unmarshal([]byte(f2), &d2)
d1.PrintData()
d2.PrintData()
}