2017-04-21 3 views
1

私はちょうど覚えていますに行きました。私は関数にslicesを渡すことに疑問を持っています。スライスのコピーを関数に渡すには?

私は間違っていないんだ場合、私はこのような何かのであればslicesは、ゴーに参照によって渡されます

package main 

import "fmt" 

func main() { 
    slice := []int{1, 2, 3, 4, 5} 
    fmt.Println(slice) 
    testSlice(slice) 
    fmt.Println(slice) 
} 

func testSlice(slice []int) { 
    slice[0] = 5 
    slice[4] = 1 
} 

testSlice機能は、実際に元sliceの値が変更されますので、参照渡し(デフォルト)。

sliceのコピーをtestSliceの機能に直接渡すことは簡単な方法ですか?

私はsliceのコピーを作成するには、このような何かを行うことができますを確認します。

package main 

import "fmt" 

func main() { 
    slice := []int{1, 2, 3, 4, 5} 
    fmt.Println(slice) 
    testSlice(slice) 
    fmt.Println(slice) 
} 

func testSlice(slice []int) { 
    var newSlice []int 
    for i := 0; i < len(slice); i++ { 
     newSlice = append(newSlice, slice[i]) 
    } 
    newSlice[0] = 5 
    newSlice[4] = 1 
} 

しかし、それはそれらのそれぞれをコピーし、元のslice内のすべての値を通過する必要があり、それはいないようですすばらしい解決策になる。

答えて

2

組み込み関数copyfunc copy(dst, src []T) intがあります。これはおそらくあなたが探しているものです。任意のタイプのスライスを別のスライスにコピーします。 docsから

コピー機能は、異なる長さのスライスとの間のコピーをサポートする(それは要素のみの少ない数までコピーされます)。さらに、コピーでは、同じ基本アレイを共有するソーススライスと宛先スライスを処理し、重複するスライスを正しく処理できます。

ので

list := []string{"hello", "world"} 
newList := make([]string, len(list)) 
n := copy(newList, list) 
// n is the number of values copied 

は値ではなく、メモリ内の参照を共有する新しいスライスnewList、にlistをコピーします。 intcopy returnsはコピーされた値の数です。


代わりに、Kostixのコメントから、スライスを空のスライスに追加することができます。それはそれをコピーするようなものです。それは慣用的ではないかもしれませんが、スライスをfuncコピーとしてソートに渡すことができます。これを行うと、豊富なコメントをお勧めします。

thisFuncTakesSliceCopy(append([]string(nil), list...)) 

楕円(...)を覚えて、別のスライスにスライスを追加します。

+0

ありがとう@Nevermore、これは 'スライス'をコピーするよりエレガントな方法です。念のため。 'スライス'コピーを関数に直接渡すことはできません。唯一の方法は、新しい 'slice 'を手動で作成し、オリジナルの' slice'から値をコピーすることです。私は 'C++ 'から来ているので私はそれを求めているだけで、参照や値渡しでベクトルを渡すことができます。 – KelvinS

+0

@KelvinSalton goには「参照渡し」という概念は全くありません。すべてが価値によって渡されます。スライスとは、基本となる配列への記述子です。配列のその部分のコピーが必要な場合は、コピーを作成する必要があります。Goの焦点は、「エレガントな」または「構文的な砂糖」ではなく「明示的」である: – Volker

+0

ありがとう@Volker、それはずっとはっきりしている。 – KelvinS

関連する問題