多个Struct开关?

时间:2014-10-23 03:07:43

标签: struct go

假设我有一个应用程序以两种不同的格式接收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类型。 如何使这种开关结构选择工作?

here is a non working example

2 个答案:

答案 0 :(得分:5)

您可以在方法返回的界面上type switch

switch ps := parsedStruct.(type) {
    case *F1:
        log.Println(ps.Col1)
    case *F2:
        log.Println(ps.Col3)
}

...等。请记住,要使encoding/json包正确解码(通过反射),您的字段需要导出(大写第一个字母)。

工作样本:http://play.golang.org/p/8Ujc2CjIj8

答案 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()
}

http://play.golang.org/p/5haKpG7MXg