2017-04-25 140 views
4

我试图将切片中的某个位置从一个位置移动到另一个位置。 Go Playground将切片项从一个位置移动到另一个位置

indexToRemove := 1 
indexWhereToInsert := 4 

slice := []int{0,1,2,3,4,5,6,7,8,9}  

slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...) 
fmt.Println("slice:", slice)  

newSlice := append(slice[:indexWhereToInsert], 1) 
fmt.Println("newSlice:", newSlice) 

slice = append(newSlice, slice[indexWhereToInsert:]...) 
fmt.Println("slice:", slice) 

这会产生下列输出:

slice: [0 2 3 4 5 6 7 8 9] 
newSlice: [0 2 3 4 1] 
slice: [0 2 3 4 1 1 6 7 8 9] 

但我希望的输出是这样的:

slice: [0 2 3 4 5 6 7 8 9] 
newSlice: [0 2 3 4 1] 
slice: [0 2 3 4 1 **5** 6 7 8 9] 

哪里是我的错吗?

+0

切片是引用数组的对象(Flimzy的答案)。另外请记住,你实际上可以使用裸阵列,但与切片相比,它们相当笨拙。尽管如此,它们在某些情况下仍然有用。 – RayfenWindspear

回答

2

问题是newSlice不是slice的独特副本 - 它们引用相同的底层阵列。

因此,当您指定newSlice时,您正在修改基础阵列,因此也修改了slice

为了解决这个问题,你需要做一个明确的副本:

Playground

package main 

import (
    "fmt" 
) 

func main() { 

    indexToRemove := 1 
    indexWhereToInsert := 4 

    slice := []int{0,1,2,3,4,5,6,7,8,9} 

    val := slice[indexToRemove] 

    slice = append(slice[:indexToRemove], slice[indexToRemove+1:]...) 
    fmt.Println("slice:", slice)  

    newSlice := make([]int, indexWhereToInsert+1) 
    copy(newSlice,slice[:indexWhereToInsert]) 
    newSlice[indexWhereToInsert]=val 
    fmt.Println("newSlice:", newSlice) 
    fmt.Println("slice:", slice) 

    slice = append(newSlice, slice[indexWhereToInsert:]...) 
    fmt.Println("slice:", slice)  
} 

(请注意,我还添加了val变量,而不是硬编码1作为值要插入)

+0

这解释了很多!我认为append返回一个新的切片。坦克! – David

+0

@David:[Go Slices:usage and internals](https://blog.golang.org/go-slices-usage-and-internals)对你来说会是一些不错的阅读。 – Flimzy

+1

这是一个移动版本,无需复制https://play.golang.org/p/KGcvoIF3bK – David

相关问题