【问题标题】:Multiple Struct switch?多结构切换?
【发布时间】:2014-10-23 03:07:42
【问题描述】:

假设我有一个应用程序接收两种不同格式的 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 数据转换为结构: 类型点{ 点类型字符串 数据 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
}

这不起作用,因为返回的值是一个接口,而不是正确的结构类型。 我怎样才能使这种开关结构选择工作?

here is a non working example

【问题讨论】:

  • 另一种方法是使用地图(本机 json 包支持)。
  • Sebastien 我不确定我是否理解。你有什么我可以检查的例子吗?

标签: struct go


【解决方案1】:

你可以在你方法返回的接口上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

【讨论】:

  • 我想就是这样!。有没有一种方法可以返回正确的类型对象,而不必在每个 switch case 中执行?
  • 不,没有……那是行不通的。您需要知道对象的类型 .. 因为它们有不同的字段。类型开关允许您知道您在给定上下文中访问的对象。如果您改为选择两个对象具有相同的字段名称......那么您可以让它们实现一个接口,其方法将值返回给您。除此之外,这是唯一的方法。
  • 当然,您的另一个选择是完全删除对象,然后将其反序列化为map[string]string。不过,代码看起来不会那么容易......
【解决方案2】:

另一种方法是使用地图(由本机 json 包支持)。

这里我假设每个数据属性(col1,col2 ...)都存在,但是maps允许你检查它。

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

【讨论】:

    猜你喜欢
    • 2010-10-27
    • 2020-09-12
    • 2015-08-31
    • 2017-09-13
    • 2021-12-04
    • 2012-02-25
    • 2018-12-09
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多