切片副本未按预期工作

时间:2016-04-27 11:15:41

标签: go slice

在以下Go程序中,我创建了mySlice1,其中包含6个元素。 mySlice2初始化为3个元素。

mySlice1我将前两个元素带入mySlice2。同样使用切片的copy功能,mySlice1的3个元素将被覆盖为mySlice2

package main

import "fmt"

func main() {

    mySlice1 := []int{1, 3, 5, 7, 9, 11}
    mySlice2 := make([]int,3)
    mySlice2 = mySlice1[0:2]
    copy(mySlice2,mySlice1)
    fmt.Printf("%T\t%T\n", mySlice1,mySlice2)
    fmt.Println(mySlice1,mySlice2)
}

但是在打印mySlice2时,我只能获得两个元素。

$ go run main.go
[]int   []int
[1 3 5 7 9 11] [1 3]

使用mySlice2函数时,为什么copy不会被覆盖?

3 个答案:

答案 0 :(得分:4)

如果您希望mySlice2包含3个元素,则应使用:

myslice2 = mySlice1[0,3]

或者只是:

copy(mySlice2,mySlice1)

您确实创建了一个长度为3的切片,但是然后您将其重新指定为长度为2.您可以在分配之前和之后使用len(mySlice2)查看

答案 1 :(得分:2)

此时您正在重新初始化mySlice2变量:
mySlice2 = mySlice1[0:2]

因此,先前对具有3个元素的切片的引用已经消失。

要解决此问题,只需删除此句并重新运行该程序。

答案 2 :(得分:0)

您的代码按预期工作。

您正在将mySlice1中的前三个值复制到mySlice2,因此您实际上是复制了指向mySlice1切片中前三项的内存地址。

当你声明mySlice2实际上你正在用零来初始化切片索引值时(这就是Go切片的工作方式)。然后将slice1中的前三个值复制到slice2中。这并不意味着mySlice2值已更改。如果你更改mySlice2 0 th 索引让我们说mySlice1第一个值相应地改变,因为正如我所提到的那样,索引是由它们的内存地址引用的

package main

import "fmt"

func main() {

    mySlice1 := []int{0, 3, 5, 7, 9, 11}
    mySlice2 := make([]int,3)
    mySlice2 = mySlice1[0:2]
    mySlice2[0] = 1

    copy(mySlice2,mySlice1)
    fmt.Printf("%T\t%T\n", mySlice1,mySlice2)
    fmt.Println(mySlice1,mySlice2)

    // Output
    // [1 3 5 7 9 11] [1 3]
}
相关问题