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
      			}
      		}
      	}
        // ......省略
      }
      

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