为什么会这样:
slice := make([]string, 0, 10)
sliceptr := &slice
这也是:
sliceptr := &[]string{"foo","bar","baz"}
但这并不是:
sliceaddrval := reflect.ValueOf([]string{"foo","bar","baz"}).Addr()
恐慌:reflect.Value.Addr of unaddressable value
编辑:总的来说,我尝试做的是采用一个未知类型的结构,制作一个这种类型的结构并返回一个指针(我使用github.com) / jmoiron / modl,它需要一个指向切片的指针来填充SQL查询的结果。)
答案 0 :(得分:5)
reflect.Value
需要interface{}
,并且interface{}
的值不能用于更改原始值。否则,当您甚至打算将指针传递给它时,最终可能会在struct
中更改代码更改数据。 (或者,在这种情况下,更改按值传递的切片的长度。)因此,如果您使用地址,则必须在ValueOf
之前执行此操作。
要制作指向切片的指针,您可以将其传递给append
到它的包(例如modl
或Google App Engine GetMulti
),您就可以了使用类似http://play.golang.org/p/1ZXsqjrqa3的内容,复制到这里:
package main
import (
"fmt"
"reflect"
)
type row struct { i, j int }
func main() {
aRow := row{}
valueType := reflect.ValueOf(aRow).Type()
slicePtrVal := reflect.New(reflect.SliceOf(valueType))
slicePtrIface := slicePtrVal.Interface()
getQueryResults(slicePtrIface)
fmt.Println(slicePtrIface)
}
// standing in for `modl` or whatever populates the slice
func getQueryResults(slicePtr interface{}) {
sPtr := slicePtr.(*[]row)
(*sPtr) = append((*sPtr), row{1,3})
}
在reflect.Value
中附加到{x}}的切片需要另外几行reflect
,但听起来您正在使用的包会为您处理该部分。有关一般信息,执行追加的代码位于http://play.golang.org/p/m3-xFYc6ON及以下位置:
package main
import (
"fmt"
"reflect"
)
type row struct { i, j int }
func main() {
aRow := row{}
// make a pointer to an empty slice
rowType := reflect.ValueOf(aRow).Type()
slicePtrVal := reflect.New(reflect.SliceOf(rowType))
slicePtrIface := slicePtrVal.Interface()
// append a zero row to it
rowVal := reflect.Zero(rowType)
sliceVal := reflect.Indirect(slicePtrVal)
sliceVal.Set(reflect.Append(sliceVal, rowVal))
fmt.Println(slicePtrIface)
}