Go基礎數據結構學習——slice

Go基礎數據結構學習——slice

slice

  1. Slice切片:是一個數組某部分的引用,在內存中是一個包含三個域的結構體,第一個是指向數據的第一個元素的指針,第二個是切片的長度,第三個是切片的容量

    type slice struct {
    	array unsafe.Pointer
    	len   int
    	cap   int
    }
    
  2. slice不能簡單使用==來測試兩個slice是否擁有相同的元素,對於引用類型,操作符==檢查的是引用相等性,即是否指向相同的元素。如果切片類型是字節([]byte),可以使用bytes.Equal比較,其他的類型就不可以了。slice唯一允許的比較操作就是和nil做比較。

    func Equal(a, b []string) bool {
      if len(a) != len(b){
        return false
      }
      for i := range a{
        if a[i] != b[i]{
          return false
        }
      }
      return true
    }
    
  3. 注意:

    • slice的零值是nil

    • 值爲nil的slice長度和容量都是0

      var s []string 				// len(s) == 0,s == nil
      s = nil        				// len(s) == 0,s == nil
      s = []string(nil)     // len(s) == 0,s == nil
      s = []string{}	      // len(s) == 0,s != nil
      s = make([]string, 3) // len(s) == 0,s != nil
      

      檢查slice是否是空可以使用len(s) == 0而不是s == nil,s爲nil也可能爲空

    • 重新切分切片不會複製底層數組

    • make([]T, len) 和make([]T, len, cap):初始化的時候如果使用make([]T, 3) 的含義是len=3,且 cap=3的數組,此時數組中已經存在3個nil的元素了,如果使用make([]T, 0, 3)含義是len=0,cap=3的數組,數組中爲空

    • 數組是值拷貝而切片是引用

  4. slice的擴充:每次調用都必須檢查slice是否有足夠的容量來存儲數組中的新元素,

    1. 如果slice容量足夠,他就會定義一個新的slice,仍然應用原始底層數組,然後將新元素複製到新的位置並返回新的slice;

    2. 如果新的大小是當前大小的兩倍以上,則大小爲新大小

    3. 如果當前大小小於1024,按每次兩倍增長,否則按當前大小四分之一增長,知道增長的大小超過或等於新大小

      // runtime/slice.go
      func growslice(et *_type, old slice, cap int) slice {
        // ......省略
      	newcap := old.cap
      	doublecap := newcap + newcap
      	if cap > doublecap {
      		newcap = cap
      	} else {
      		if old.len < 1024 {
      			newcap = doublecap
      		} else {
      			// Check 0 < newcap to detect overflow
      			// and prevent an infinite loop.
      			for 0 < newcap && newcap < cap {
      				newcap += newcap / 4
      			}
      			// Set newcap to the requested cap when
      			// the newcap calculation overflowed.
      			if newcap <= 0 {
      				newcap = cap
      			}
      		}
      	}
        // ......省略
      }
      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章