美文网首页
GO中的切片

GO中的切片

作者: 暂且听风吟一曲 | 来源:发表于2016-12-26 22:17 被阅读0次

    Refs

    原文:Go Slices: usage and internals

    The Go Programming Language Specification

    Effect GO

    Array

    Go中的数组对象代表着整个数组,而是指向首元素的指针。当传递数组对象时,传递的是整个数组的值。

    b := [...]string{"a", "b", "c"}
    

    Slices

    Slices的声明与Array类似,但是省略了长度信息。

    l := []string{"a", "b", "c"}
    

    或者使用内置的make方法

    l = make([]string, len, cap)
    

    Array和Slices的切片操作会产生Slices对象

    Slices实现原理
    • make([]byte, 5)会产生下图中的结构:

    • s = s[2:4]后cap会剔除前方的长度(5 - 2 = 3):

    • 切片操作没有拷贝Slice的数据,而是创建了左侧的结构并把指针指向起始位置。因此,操作切片结果是,会影响到原有的数据;

    • s = s[:cap(s)]来使用全部空间;

    COPY

    增加slice容量只能通过分配新的slice空间、拷贝数据来实现。

    s := [3]byte{'a', 'b', 'c'}
    t := make([]byte, len(s), (cap(s) + 1) * 2)
    copy(t, s)
    s = t
    
    APPEND
    func AppendByte(slice []byte, data ... byte) []byte {
      m := len(slice)
      n := m + len(data)
      if n > cap(slice) {
        newSlice := make([]byte, (n + 1) * 2)
        copy(newSlice, slice)
        slice = newSlice
      }
      slice = slice[0:n]      // len == cap
      copy(slice[m:n], data)
      return slice
    }
    
    • 添加元素
    p := []byte{2, 3, 5}
    p = p.append(p, 1, 2)
    
    • 添加slice
    a := []string{"a", "b", "c"}
    b := []string{"e", "f", "g"}
    b = append(a, b...)
    
    func Filter(s []int, fn func(int) bool) [] int {
      var p []int   // nil
      for _, v := range s {
        if fn(v) {
          p = append(p, v)
        }
      }
      return p
    }
    
    疑思

    当只需要大量数据的一小部分时,如果对大量数据做切片操作,那么这些数据都会保留在内存中。例如,读取文件中数据并返回特定片断的程序。
    这种情况下,建议构造目标数据的切片进行返回,这样GC就能够及时回收无用的数据。

    相关文章

      网友评论

          本文标题:GO中的切片

          本文链接:https://www.haomeiwen.com/subject/pjzjvttx.html