2017-04-25 86 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

相關問題