スライスに対するいくつかの理解

13866 ワード

文書ディレクトリ
  • スライス
  • 基本的な構成
  • 一般的な初期化操作
  • スライスに対する操作
  • 追加
  • 拡張
  • 削除
  • 使用テクニック
  • メモリリーク可能
  • スライス
    きほんこうぞう
    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メカニズムのため、メモリリファレンスが存在する限り、メモリ全体が解放されません.システム全体のパフォーマンスが低下する可能性があります.興味のあるデータだけを単独でスライスしたほうがいいです.