我正在为一个特定的 API 开发一个客户端,我构建了几个结构(每个路由一个)。
API 适用于页面,因此我有 getter 返回结构的 slice 。这是通过一个通用函数完成的,该函数采用一个接口(interface),该接口(interface)应该是指向所需结构的一部分的指针,因此我可以使用 json
包中的 Unmarshal
。
我面临的问题是我想在一个请求中获取所有页面,但为了做到这一点,我需要连接多个 slice 。
我尝试使用 reflect
来做到这一点,但我只能设法创建一个新 slice ,而不会实际改变我的接口(interface)指向的值。
这是我的部分代码:
func concatenateSlice(dst, src interface{})(){
dstValue := reflect.ValueOf(dst)
srcValue := reflect.ValueOf(src)
if srcValue.Type() != dstValue.Type(){
return
}
switch srcValue.Kind(){
case reflect.Ptr, reflect.Slice:
dstValuePoint := reflect.Indirect(dstValue)
srcValuePoint := reflect.Indirect(srcValue)
reflect.Copy(dstValuePoint, reflect.AppendSlice(dstValuePoint, srcValuePoint))
}
}
对于草率的帖子,我很抱歉,这是我第一次使用 stackoverflow。
最佳答案
你不应该使用 reflect.Copy()
复制结果 slice (追加后),因为目标没有足够的空间。 reflect.AppendSlice()
不会更改 dst
指向的 slice ,它会在需要时分配一个新 slice ,并返回新 slice (更准确地说是持有它的 reflect.Value
)。
您应该做的是将 reflect.AppendSlice()
返回的 slice 设置为 dst
指向的值,只需使用 Value.Set()
方法。需要注意的一件事是您不是设置 slice 指针而是设置 slice ,因此首先调用例如Value.Elem()
在调用 Set()
之前。
看这个例子:
func concatenateSlice(dst, src interface{}) {
dv := reflect.ValueOf(dst)
sv := reflect.ValueOf(src)
if dv.Type() != sv.Type() {
return
}
dv2 := reflect.AppendSlice(dv.Elem(), sv.Elem())
dv.Elem().Set(dv2)
}
测试它:
dst := []int{1, 2}
src := []int{3, 4}
concatenateSlice(&dst, &src)
fmt.Println(dst)
输出(在 Go Playground 上尝试):
[1 2 3 4]
关于pointers - 从作为接口(interface)传递的指针连接 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51628655/