将 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
值。
我得到了一个映射[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
值。