当前位置: 首页 > 面试题库 >

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

柯默
2023-03-14
问题内容

如何运作:

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查询结果填充的切片的指针)。


问题答案:

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}) 
}

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)
}


 类似资料:
  • 我的问题是为什么找不到“name”字段?

  • 问题内容: 我发现切片图功能和通道经常一起作为 参考类型 提及。但是我注意到,切片的东西不会表现出参考行为,就像它们会过时一样: 要么 通常,我会通过牢记切片描述符实现的内部组件来理解这一点:切片值可以视为len,cap和data指针的结构。 但是地图值永远不需要像 为什么?映射值仅仅是指向映射描述符的指针吗?如果是这样,为什么还不这样做呢? 问题答案: 在Go中,没有像C ++中那样的引用类型。

  • 问题内容: 我需要在Go中制作切片的副本,并阅读文档,这里有一个复制功能供我使用。 内置复制功能将元素从源切片复制到目标切片。(在特殊情况下,它还会将字节从字符串复制到字节切片。)源和目标可能会重叠。复制返回复制的元素数量,该数量将是len(src)和len(dst)的最小值。 但是当我这样做时: 与以前一样,我是空的(甚至尝试使用): 您可以在运动场上查看。那为什么不能复制切片? 问题答案: 内

  • 问题内容: 我一直在阅读Go,并为这个基本问题感到困惑。 在Go中,很明显,切片更灵活,并且在需要一系列数据时通常可以代替数组使用。 阅读了大多数文档,他们似乎鼓励开发人员只使用切片而不是数组。我得到的印象是,创建者可以简单地将数组设计为可调整大小的,而无需整个切片部分即可完成。实际上,这样的设计会使该语言更易于理解,甚至鼓励使用更多惯用的代码。 那么,为什么创建者首先要允许数组呢?什么时候可以使

  • 我需要在Go中复制一个切片,并读取文档。有一个复制功能可供我使用。 copy内置函数将元素从源片复制到目标片。(作为一种特殊情况,它还会将字节从字符串复制到字节片。)源和目标可能重叠。Copy返回复制的元素数,它是len(src)和len(dst)中的最小值。 但当我这样做的时候: 我的和以前一样是空的(我甚至尝试使用): 你可以去游乐场看看。那么为什么我不能复制一个切片呢?

  • 问题内容: 什么是反射,为什么有用? 我对Java特别感兴趣,但是我认为原理在任何语言中都是相同的。 问题答案: 名称反射用于描述能够检查同一系统(或本身)中的其他代码的代码。 例如,假设您在Java中有一个未知类型的对象,并且想在该对象上调用“ doSomething”方法(如果存在)。除非对象符合已知的接口,否则Java的静态类型化系统并不是真正为支持该类型而设计的,但是使用反射,您的代码可以