0

我有一个 map[string]interface{} 因为解码为 JSON;对于普通数据,接口大多只是一个数字,但类型为字符串,如下所示:

var a interface{}
a="3"

然后所有数据都将存储到struct中。

type someStruct struct {
   ID string
   Number1 int
   Number2 int
   Number3 int
   Number4 int
}

所以我需要将 interface 转换为 int,但不能轻松有效地做到这一点,因为只有代码会是https://play.golang.org/p/oktbvTUbk93,非常烦人,如果你看代码似乎不可读记住我应该处理所有可能的错误

我想将它直接转换为 int,我一直在寻找解决方案,但任何这种转换都可以按我的意愿工作https://play.golang.org/p/Dw67U6kZwHC

如果您想知道为什么我不直接将其解码为结构,那是因为它是动态数据,实际解码是这样发生的:

type dataIn struct {
   Code int         `json:"code"`
   ID   string      `json:"id"`
   Data interface{} `json:"data"`
}

然后我根据code和id来处理Data,它们都是不同的数据结构,所以我不能直接用JSON处理

4

3 回答 3

3

创建一个辅助函数,在一个地方为您解析和验证:

func parseInt(i interface{}) (int, error) {
    s, ok := i.(string)
    if !ok {
        return 0, errors.New("not string")
    }
    return strconv.Atoi(s)
}

你可以在需要的地方使用它。这是一个完整的示例,其中我还使用了另一个帮助函数,它负责错误处理:

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\n", data)

上面的输出(在Go Playground上试试):

{ID:asdsa Title:asdas Number1:1 Number2:2 Number3:3 Number4:4}

另请注意,开源包github.com/icza/dyno应该可以帮助您轻松处理动态对象。(披露:我是作者。)dyno.GetInteger()例如,它有一个函数,能够int64从多种类型(如整数、浮点数、字符串等)中提取值。

于 2018-03-30T09:01:57.087 回答
0

听起来您需要的是主结构上的自定义解组 json 方法。首先,解组到您的主结构中以获取您的代码和 id,然后在 switch 语句中使用它们来确定用于其余数据的结构并解组到该结构中,在您的数据字段中搅拌该结构。

于 2018-03-30T06:56:43.573 回答
0

我仍然没有得到你所说的结构是动态生成的部分。无论如何,您可以附加一个结构方法,它可以进行 int 转换。如果Data类型的字段interface{}总是要保存整数,你可以试试这个:

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(),
}
于 2018-03-30T08:14:58.560 回答