2017-10-18 33 views
-1

私の目的は、特定のスライスから一つの要素を削除することで、コードのようなものです:なぜ関数呼び出しによってスライスの長さや容量を変更できないのですか?

func main() { 
    s := []int{0, 1, 2, 3, 4} 
    remove(s, 3) 
    fmt.Println(s, len(s), cap(s)) 
} 

func remove(s []int, idx int) { 
    if idx < 0 || idx >= len(s) { 
     return 
    } 
    copy(s[idx:], s[idx+1:]) 
    s = s[:len(s)-1] 
    fmt.Println(s, len(s), cap(s)) 
} 

が、出力が示した:

[0 1 2 4] 4 5 [0 1 2 4 4] 5 5

私が知っているように、スライスはに渡されます参照型としての関数呼び出し、なぜそれを変更できないのでしょうか?

1)ポインタ下地アレイ

2)長

3)容量

にあなたが関数にスライスを渡すときは、コピーを渡す:

+5

スライスは参照型ではありません**、実際はそうではありません。 –

+1

また、[Golangはスライスにアイテムを追加します](https://stackoverflow.com/questions/20195296/golang-append-an-item-to-a-slice)の複製も可能です。 –

+0

スライスはリファレンスタイプではありませんが、メモリを浪費するのを避けるためにポインタを使用しています(https://play.golang.org/p/8CBxmyBJjl)。これは、メモリが2つのスライス間で共有されていることを意味しますが、長さとキャップが異なる場合があります。彼らは基本的に2つの異なる項目です。スライスについての詳細は、Goのブログのエントリ「Go Slices:usage and internals」、特に[このセクション](https://blog.golang.org/go-slices-usage-and-internals#TOC_4)を参照してください。 –

答えて

5

スライスの3つの値を保持しますこれら3つの値すべてのしたがって、長さと容量を変更することはできませんが、基本となる配列へのポインタがあるので、配列内の値を変更することができます。

2

スライスはポインタ型ではありません。フードスライスの下には、長さ、容量、配列へのポインタの3つの値があります。あなたが価値によってそれを渡すとき、あなたは長さと容量のコピーを手に入れます - あなたはそれらをあなたのために変えることができます。配列の変更は関数の外で見ることができます。

そのような結果が得られる場合

関連する問題