提问人:xc wang 提问时间:6/26/2021 最后编辑:iczaxc wang 更新时间:6/26/2021 访问量:997
如何使用类似 if-else 的条件在 GO 中动态声明变量的 Type?
How to declare the Type of a variable dynamically in GO, using if-else-like conditions?
问:
给定两种类型
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)
在围棋中,有没有可能实现这个目标?
答:
3赞
icza
6/26/2021
#1
您必须将指向预期数据类型的指针传递给 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); err != nil {
panic(err)
}
fmt.Printf("outer type is %T \n", data)
fmt.Printf("outer value is %+v \n", 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]]}
请检查相关/可能的重复项,以进一步详细说明问题:
如何告诉 json。取消编组以使用 struct 而不是 interface
评论
0赞
xc wang
6/26/2021
在您的代码中,似乎是 类型,值为 ,但是当使用 访问其指向值时,编译器会报告错误。您能否对此进行解释并给出访问“*数据”的方法?谢谢。data
*main.A
&{ID:abc Content:[1 2 3]}
temp := *data
invalid operation: cannot indirect data (variable of type interface{})
0赞
icza
6/26/2021
@xcwang有静态类型,但动态类型。要访问存储在接口值中的值,请使用类型断言,例如 .data
interface{}
*main.A
data.(*A).ID
评论