如何解决如何使用类似if-else的条件在GO中动态声明变量的类型?
给定两种类型
type A struct {
ID string
Content []int
}
和
type B struct {
ID string
Content map[string][]int
}
并且我需要一个函数来告诉我以后根据条件使用哪种类型(目的是正确解组 json 字符串)。我想要一个像
这样的功能func assign_typed_data(header string) interface{} {
switch header {
case "A" :
d := new(A)
fmt.Printf('inner type is %T \n',*d) // inner type is A
return *d
case "B" :
d := new(B)
fmt.Printf('inner type is %T \n',*d) // inner type is B
return *d
default:
}
}
在外部代码中,我可以调用它并解组 json,如下所示,但返回值变为“map[string]interface{}”。
header := "A"
data := assign_typed_data(header)
fmt.Printf('outter type is %T \n',data) // outter type is map[string]interface{}
json.Unmarshal(json_data,&data)
我也在不调用函数的情况下直接在外部代码中尝试了简单的 if-else 语句,如下所示,但由于定义的作用域是本地的,也失败了。
if header == "A" {
data := *new(A)
}else if header == "B" {
data := *new(B)
}
json.Unmarshal(json_data,&data)
有没有办法在 GO 中实现这个目标?
解决方法
您必须将指向预期数据类型的指针传递给 json.Unmarshal()
。即,*A
或 *B
。
然而,assign_typed_data()
返回 interface{}
并且您获取其地址,因此您将传递 *interface{}
。
更改assign_typed_data()
以返回指针值*A
或*B
,并将data
原样传递给json.Unmarshal()
,因为它已经持有一个指针值:
func createValue(header string) interface{} {
switch header {
case "A":
d := new(A)
fmt.Printf("inner type is %T \n",d) // inner type is *A
return d
case "B":
d := new(B)
fmt.Printf("inner type is %T \n",d) // inner type is *B
return d
default:
return nil
}
}
测试:
s := `{"ID":"abc","Content":[1,2,3]}`
data := createValue("A")
if err := json.Unmarshal([]byte(s),data); err != nil {
panic(err)
}
fmt.Printf("outer type is %T \n",data)
fmt.Printf("outer value is %+v \n",data)
s = `{"ID":"abc","Content":{"one":[1,2],"two":[3,4]}}`
data = createValue("B")
if err := json.Unmarshal([]byte(s),data)
哪些输出(在 Go Playground 上试试):
inner type is *main.A
outer type is *main.A
outer value is &{ID:abc Content:[1 2 3]}
inner type is *main.B
outer type is *main.B
outer value is &{ID:abc Content:map[one:[1 2] two:[3 4]]}
请检查相关/可能的重复项,进一步详细说明问题:
Golang interface{} type misunderstanding
Is it possible to dynamically set the output of json.Unmarshal?
How to tell json.Unmarshal to use struct instead of interface
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。