我得到了一个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}

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

  • 顺便说一下,您的解决方案非常简单。 尽管这解决了实际的问题,但是有一个解决方案可以不必首先转换任何内容

我仍然没有得到您所说的结构是动态生成的部分。无论如何,您可以附加一个进行int转换的struct方法。如果类型为interface{}Data字段始终保留整数,则可以尝试以下操作:

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会使我的代码更大,谢谢!