スライスに対するいくつかの理解
13866 ワード
文書ディレクトリスライス 基本的な構成 一般的な初期化操作 スライスに対する操作 追加 拡張 削除 使用テクニック メモリリーク可能 スライス
きほんこうぞう
1つのスライスは、C++のvectorと同様に、データポインタに長さと容量を加えたものです.
一般的な初期化操作
スライスの操作
追加
一般的にappendメソッドを使用してスライスに要素を追加します.
2行目は、最初に要素を挿入します.通常、メモリの再割り当てが発生し、パフォーマンスが低下します.
copy法とappend法を組み合わせて,いくつかの機能を実現することができる.
copyは、複数のスライスコピー時にメモリを共有したときに修正されたバグを回避します.
かくさんようりょう
スライスを追加すると、スライスの拡張操作が自動的にトリガーされます.
具体的な拡張ポリシーについては、capが1024未満の場合、毎回2倍になることが最も基本的である.1024を超えると毎回1.25倍になります.
しかし、このポリシーは、1つの要素を追加するたびに適用され、1回に複数の要素を追加する場合、必ずしもこの拡張ポリシーではありません.
現在のcapが4の場合、lenは3、appendは1回6要素です.ではこのとき、append操作後のcapは9です.
そして具体的なsliceのタイプはcapにも関係しています.
この基本原理はgoのメモリ管理操作に関して、よく分かりません.
https://blog.csdn.net/weixin_34100227/article/details/91373911
削除
テクニックの使用
メモリ漏洩の可能性
GoのGCメカニズムのため、メモリリファレンスが存在する限り、メモリ全体が解放されません.システム全体のパフォーマンスが低下する可能性があります.興味のあるデータだけを単独でスライスしたほうがいいです.
きほんこうぞう
type struct {
Data uintptr
Len int
Cap int
}
1つのスライスは、C++のvectorと同様に、データポインタに長さと容量を加えたものです.
一般的な初期化操作
var (
a []int // nil
b = []int{} // , nil
c = []int{1,2,3} // len,cap 3
d = c[:2] // cap 3,len 2。 c
e = c[0:2:cap(c)] // cap 3,len 2。 c
f = c[:0] // cap 3,len 0。
g = make([]int,3) // cap 3,len 3。 nil
h = make([]int,2,3) // cap 3,len 2。 nil
)
スライスの操作
追加
一般的にappendメソッドを使用してスライスに要素を追加します.
a = append(a,0)
a = append(0,a)
2行目は、最初に要素を挿入します.通常、メモリの再割り当てが発生し、パフォーマンスが低下します.
copy法とappend法を組み合わせて,いくつかの機能を実現することができる.
a = append(a,0)
copy(a[i+1:0],a[i:]) // a[i:]
a[i] = x
copyは、複数のスライスコピー時にメモリを共有したときに修正されたバグを回避します.
かくさんようりょう
スライスを追加すると、スライスの拡張操作が自動的にトリガーされます.
具体的な拡張ポリシーについては、capが1024未満の場合、毎回2倍になることが最も基本的である.1024を超えると毎回1.25倍になります.
しかし、このポリシーは、1つの要素を追加するたびに適用され、1回に複数の要素を追加する場合、必ずしもこの拡張ポリシーではありません.
現在のcapが4の場合、lenは3、appendは1回6要素です.ではこのとき、append操作後のcapは9です.
そして具体的なsliceのタイプはcapにも関係しています.
package main
import "fmt"
func main() {
a := []byte{1, 0}
a = append(a, 1, 1, 1)
fmt.Println("cap of a is ", cap(a))
b := []int{23, 51}
b = append(b, 4, 5, 6)
fmt.Println("cap of b is ", cap(b))
c := []int32{1, 23}
c = append(c, 2, 5, 6)
fmt.Println("cap of c is ", cap(c))
type D struct {
age byte
name string
}
d := []D{
{1, "123"},
{2, "234"},
}
d = append(d, D{4, "456"}, D{5, "567"}, D{6, "678"})
fmt.Println("cap of d is ", cap(d))
}
cap of a is 8
cap of b is 6
cap of c is 8
cap of d is 5
この基本原理はgoのメモリ管理操作に関して、よく分かりません.
https://blog.csdn.net/weixin_34100227/article/details/91373911
削除
a = []int{1,2,3}
a = a[:len(a) - N] // N
a = a[N:] // N
a = a[:i+copy(a[i:],a[i+N:])] // N
テクニックの使用
メモリ漏洩の可能性
GoのGCメカニズムのため、メモリリファレンスが存在する限り、メモリ全体が解放されません.システム全体のパフォーマンスが低下する可能性があります.興味のあるデータだけを単独でスライスしたほうがいいです.