为什么我不能用反射来获取切片的地址?

Bra*_*ody 1 reflection go slice

为什么这样有效:

slice := make([]string, 0, 10)
sliceptr := &slice
Run Code Online (Sandbox Code Playgroud)

这个也是:

sliceptr := &[]string{"foo","bar","baz"}
Run Code Online (Sandbox Code Playgroud)

但这不是:

sliceaddrval := reflect.ValueOf([]string{"foo","bar","baz"}).Addr()
Run Code Online (Sandbox Code Playgroud)

它惊慌失措: reflect.Value.Addr of unaddressable value


编辑:总的来说,我正在尝试做的是采用一个未知类型的结构,制作一个该类型的结构,并返回一个指向它的指针(我正在使用github.com/jmoiron/modl,这需要一个指向切片的指针,以填充SQL查询的结果).

two*_*two 5

reflect.Value取一个interface{},并且interface{}一个值不能用来改变原始值.否则,struct当您甚至不打算将指针传递给它时,您最终可能会在代码中更改数据.(或者,在这种情况下,更改通过值传递的切片的长度.)因此,如果您使用地址,则必须先执行此操作ValueOf.

要创建一个指向您可以传递给它的包的指针append(如modlGoogle 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}) 
}
Run Code Online (Sandbox Code Playgroud)

附加到reflect.Value自己的切片需要另外几行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)
}
Run Code Online (Sandbox Code Playgroud)