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

Golang重用内存地址从切片复制?

衡安晏
2023-03-14
问题内容

我在正在研究的项目中遇到问题。我找到了解决方法,但是我不确定为什么我的解决方案有效。我希望对Go指针的工作方式有更多经验的人能对我有所帮助。

我有一个Model接口和一个实现该接口的Region结构。Model接口是在Region结构的指针上实现的。我也有一个Regions集合,它是Region对象的一部分。我有一种方法可以将Regions对象转换为[]
Model:

// Regions is the collection of the Region model
type Regions []Region

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, item := range *coll {
        output[idx] = &item
    }
    return output
}

当我运行此代码时,我最终获得指向该Region的第一个指针,该指针多次输出。因此,如果Regions集合具有两个不同的项目,我将获得相同的地址重复两次。在切片中设置变量之前打印变量时,它们具有正确的数据。

我有点困惑,认为Go可能在循环之间重用了内存地址。该解决方案目前正在我的测试中为我工作:

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, _ := range *coll {
        i := (*coll)[idx]
        output[idx] = &i
    }
    return output
}

这样可以在输出切片中提供两个不同地址的预期输出。

老实说,这似乎是一个范围函数在两次运行之间重用相同内存地址的错误,但我始终认为在这种情况下我会丢失某些内容。

我希望我为您解释得足够好。我很惊讶原来的解决方案没有用。

谢谢!


问题答案:

在您的第一个(无效)示例中,item是循环变量。它的地址不变,只有值。这就是为什么您在输出idx时间内获得相同地址的原因。

运行以下代码,查看运行的机制;

func main() {

    coll := []int{5, 10, 15}

    for i, v := range coll {
       fmt.Printf("This one is always the same; %v\n", &v)
       fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i])
    }
}


 类似资料:
  • 问题内容: 我有一些C方面的经验,对golang完全陌生。 现在在golang slice中是array的引用,其中包含指向slice的数组len和slice的上限的指针,但是该slice也将分配在内存中,我想打印该内存的地址。但是无法做到这一点。 问题答案: http://golang.org/pkg/fmt/ 将打印地址。

  • 问题内容: 我最近学习了Go语言,现在对以下代码感到困惑: 结果: 问题答案: c是从数组中获取的一个切片b。这不是副本,而只是的两个前两个元素的窗口b。 由于b容量为5,c可以扩展到其他3个位置(实际上,它会创建一个新的切片,但位于内存中的同一位置)。 切片的最大容量是底层数组的容量减去切片在数组中起始位置的大小: func main() { b := make([]int, 0, 5) c :

  • 问题内容: 我很好奇为什么只在var上打印内存地址就可以直接使用,但是尝试通过接口执行相同的操作却不能打印出内存地址? https://play.golang.org/p/Ko8sEVfehv 只是想在修复错误后添加它,它现在可以正常运行。测试移位内存指针 https://play.golang.org/p/BnB14-yX8B 问题答案: 因为在方法第二种情况下: 不是一个而是一个结构,是类型的

  • 在Go中,复制切片是标准费用,如下所示: 在《铁锈》中,我找不到类似的替换方法。我想到的东西是这样的: 不幸的是,我遇到了无法解决的编译错误: 如何设置?有没有更好的复制切片的方法?

  • 我有一个计划: clear()不执行任何操作。在内存监视器中,我看到内存使用量为184 Mb,清除后没有任何变化。为什么?如何清除地图的内存?

  • 1. 内存与地址 图 17.1. 邮箱的地址 我们都见过像这样挂在墙上的很多个邮箱,每个邮箱有一个房间编号,根据房间编号找到相应的邮箱投入信件或取出信件。内存与此类似,每个内存单元有一个地址(Address),内存地址是从0开始编号的整数,CPU通过地址找到相应的内存单元,取其中的指令或者读写其中的数据。与邮箱不同的是,一个地址所对应的内存单元不能存很多东西,只能存一个字节,以前讲过的int、fl