将 interface{} 直接转换为 Golang 中的 int,其中 interface 将数字存储为字符串

convert interface{} directly to int in Golang, where interface stores a number as string

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

var a interface{}
a="3"

然后所有数据将被存储到一个结构

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

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

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

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

处理

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

我还是没听懂你说结构是动态生成的部分。无论如何,您可以附加一个 struct 方法来进行 int 转换。如果类型为 interface{}Data 字段总是包含整数,你可以试试这个:

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(),
}

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

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 值。