切片复制的效果不如预期

huangapple go评论76阅读模式
英文:

Slice copy is not working as expected

问题

在下面的Go程序中,我创建了一个包含6个元素的mySlice1
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]

为什么在使用copy函数时mySlice2没有被覆盖?

英文:

In the following Go program, I am creating mySlice1 with 6 elements in it.
mySlice2 is initialized with 3 elements.

From mySlice1 I am taking 1st two elements into mySlice2. Also using copy function of slice, 3 elements of mySlice1 are overwritten to 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)
}

But while printing mySlice2 I am getting two elements only.

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

Why is mySlice2 not getting overwritten while using copy function?

答案1

得分: 4

如果你想让mySlice2有3个元素,你应该使用:

myslice2 = mySlice1[0:3]

或者只需使用:

copy(mySlice2, mySlice1)

你确实创建了一个长度为3的切片,但是你之后将其重新赋值为长度为2。你可以在赋值之前和之后使用len(mySlice2)来查看。

英文:

If you want mySlice2 to have 3 elements, you should use:

myslice2 = mySlice1[0,3]

Or just:

copy(mySlice2,mySlice1)

You did create a slice with length 3, but the you then reassign it to a length of 2. You can see it using len(mySlice2) before and after the assignments

答案2

得分: 2

你在这个地方重新初始化了mySlice2变量:mySlice2 = mySlice1[0:2]

因此,之前对包含3个元素的切片的引用已经消失了。

要解决这个问题,只需删除这句话并重新运行程序。

英文:

You are reinitializing mySlice2 variable at this point:
mySlice2 = mySlice1[0:2].

So, the previous reference to the slice with 3 elements is gone.

To remedy this, simply remove this sentence and re-run the program.

答案3

得分: 0

你的代码按预期工作。

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

当你声明mySlice2时,实际上是用零值初始化了切片索引值(这是Go切片的工作方式)。然后你将mySlice1的前三个值复制到mySlice2中。这并不意味着mySlice2的值发生了变化。如果你将mySlice2的第0个索引更改为1,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]
}

输出结果为:

[]int    []int
[1 3 5 7 9 11] [1 3]
英文:

Your code is working as expected.

You are copying the first three values from the mySlice1 into mySlice2, hence you are actually copy the memory addresses pointing to the first three items from mySlice1 slice.

When you are declaring the mySlice2 actually you are initializing the slice index values with zero's (this is how Go slices are working). Then you copy the first three values from slice1 into slice2. This does not means that mySlice2 values are changed. If you change mySlice2 0<sup>th</sup> index to let's say 1 the mySlice1 first value is changed accordingly, because as i mentioned the indexes are referenced by their memory addresses.

package main

import &quot;fmt&quot;

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(&quot;%T\t%T\n&quot;, mySlice1,mySlice2)
    fmt.Println(mySlice1,mySlice2)

    // Output
    // [1 3 5 7 9 11] [1 3]
}

huangapple
  • 本文由 发表于 2016年4月27日 19:15:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/36888178.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定