我得到了一个map [string] interface {},因为它可以解码为JSON; 对于普通数据,接口大多数只能是一个数字,但必须是字符串类型,例如:
1 2 | var a interface{} a="3" |
然后所有数据将被存储到一个结构中。
1 2 3 4 5 6 7 | type someStruct struct { ID string Number1 int Number2 int Number3 int Number4 int } |
因此,我需要将接口转换为int,但是却不能轻松高效地完成,因为只有代码是https://play.golang.org/p/oktbvTUbk93,非常烦人,如果您不喜欢代码, 请记住我应该处理所有可能的错误的事实
我想将其直接转换为int,我一直在寻找解决方案,但任何这种转换都可以按我的要求工作https://play.golang.org/p/Dw67U6kZwHC
如果您想知道为什么我不直接将其解码为struct,这是因为它是动态数据,所以实际的解码是这样的:
1 2 3 4 5 | type dataIn struct { Code int `json:"code"` ID string `json:"id"` Data interface{} `json:"data"` } |
然后我根据代码和id处理数据,它们都是不同的数据结构,因此我无法直接使用JSON处理数据
-
使用空白标识符使用值。 例如,
_, _ = ok, err 。 - 如果问题空间很大,您的代码也将很大。 这里没有魔术。 做一些编程。
- json包可以将数字编码和解码为字符串:play.golang.org/p/MdrfqQjXLkw。 有关如何处理不一致字段的信息,请参见此问题。
- @peterSO如果这样做,它将继续效率低下,因为将有一个变量分配,然后可以将其存储到destine中
- @Peter"如果您想知道为什么我不直接将其解码为struct,那是因为它是动态数据"
- 也许@Volker,但我一直在寻找最佳解决方案的意见
在一个地方创建一个帮您解析和验证的帮助函数:
1 2 3 4 5 6 7 | func parseInt(i interface{}) (int, error) { s, ok := i.(string) if !ok { return 0, errors.New("not string") } return strconv.Atoi(s) } |
您可以在需要的地方使用它。这是一个完整的示例,其中我还使用了另一个帮助程序功能,该功能负责错误处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | m := map[string]interface{}{ "number1":"1", "number2":"2", "number3":"3", "number4":"4", "ID": "asdsa", "Title": "asdas", } getInt := func(key string) int { n, err := parseInt(m[key]) if err != nil { panic(err) // Decide what you wanna do with error } return n } // converting to struct data := element{ ID: m["ID"].(string), Title: m["Title"].(string), Number1: getInt("number1"), Number2: getInt("number2"), Number3: getInt("number3"), Number4: getInt("number4"), } fmt.Printf("%+v ", data) |
上面的输出(在Go Playground上尝试):
1 | {ID:asdsa Title:asdas Number1:1 Number2:2 Number3:3 Number4:4} |
还要注意,开源软件包
- 顺便说一下,您的解决方案非常简单。 尽管这解决了实际的问题,但是有一个解决方案可以不必首先转换任何内容
我仍然没有得到您所说的结构是动态生成的部分。无论如何,您可以附加一个进行int转换的struct方法。如果类型为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | type DataIn struct { Code int `json:"code"` ID string `json:"id"` Data interface{} `json:"data"` } func (s DataIn) toInt() int { switch t := s.Data.(type) case int: i, _ := strings.Atoi(fmt.Sprintf("%v",s.Data)) return i } // using it sampleData := someStruct{ Number1: datain.toInt(), } |
- DataInt不保存数字,它保存map [string] interfarce {},其中接口内部的数字是字符串
听起来您需要的是在主结构上的自定义解组json方法。首先,解组到您的主要结构中以获取代码和ID,然后在switch语句中使用它们确定用于其余数据的结构,然后解组,在Data字段中搅动该结构。
- 对于这种情况,我将不得不解组两次,我认为这是不可能的,请您添加一个示例。
- golang.org/pkg/encoding/json/#RawMessage就是这种行为的一个很好的例子(请看解码示例)
- 另外,这就是我使用自定义解组方法讨论的事情:play.golang.org/p/ZyKhnXQ-nFB
- 我不知道我能做到这一点,而且自定义编组似乎正是我所需要的,因为使用rawMessage会使我的代码更大,谢谢!