【发布时间】:2020-02-03 12:34:17
【问题描述】:
如何将接口切片设置为结构切片?
我定义接口
type IFoo interface{
//something methods
}
我定义结构
type Foo struct{
Id int `json:"Id"`
//somethig fields
}
我创建了结构工厂,我想将 IFoo 切片更改为具体结构类型的切片
func FooFactory (p *[]IFoo) {
*p = *(*[]IFoo)(unsafe.Pointer(&[]Foo{})
//here I try something like unsafe.Pointer, reflect.SliceHeader but nothing does not works
}
然后我想将结果用于 Unmarshal json:
func main() {
var o []IFoo
FooFactory(&o)
j := []byte(`[{"Id":1}, {"Id":2}]`)
json.Unmarshal (j, &o)
fmt.Println(o)
}
我得到 [map[Id:1] map[Id:2]] 但我想得到 [{1} {2}]
如果我将 var o 定义为 []Foo 我会得到预期的结果,但我不能使用具体的结构类型作为抽象。
怎么办?感谢和抱歉我的英语不好。
【问题讨论】:
-
如果我没记错的话,
[]IFoo和encoding/json是不可能的,因为json包看起来不会比IFoo看起来“更远”以试图找出元素切片的类型。您可以做的是使用*interface{}作为FooFactory的参数,然后简单地将其设置为*p = &[]Foo{},然后将o传递给&,而不将&传递给Unmarshal。 -
... 就是说,不知道为什么你正在按照你正在做的事情做你正在做的事情,这看起来是一个非常糟糕的主意,我建议您重新考虑和重新设计。
-
@mkopriva 谢谢。我想创建一个抽象工厂来循环传递一些复杂的函数。我需要超过数百个不同的工厂,并且我不想为每种类型的结构复制/粘贴相同的数百行代码。但我同时想要强类型和“接口{}”。
-
我明白我可以直接在工厂代码中解组数据,但我不想要“脏”工厂)
-
你想使用强类型并且你不想弄脏你的工厂,这很好,只要记住,正如我已经说过的,
encoding/json不是这样工作 你想要。要么编写你自己的解组器,要么按比例缩小你的需求。