美文网首页
golang中的slice

golang中的slice

作者: 个00个 | 来源:发表于2019-04-08 16:32 被阅读0次
package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world!")

    x := []int{1,3,4,6,7}
    y := x[2:3]
    fmt.Println(y)
    fmt.Println(len(y))
    fmt.Println(cap(y))

    // 这里不会panic 因为cap(y) = 3. 其输出为 [4 6 7]
    fmt.Println(y[0:3])

    fmt.Println(y[:])
}

上面这段代码神奇的地方就是 注释的部分。 其原因可以参考这篇文章

https://tiancaiamao.gitbooks.io/go-internals/content/zh/02.2.html

关于append时, cap增长的算法 。
参考: https://studygolang.com/articles/18194?fr=sidebar

package main

import (
    "fmt"
)

func main(){
    a := []int{1,2,3}
    b := append(a,4)
    // 1. cap(a) = 3  double = 6  cap(b) = 4 < double ==> cap(b) = double = 6
    fmt.Printf("cap(a)=%v,cap(b)=%v\n",cap(a),cap(b))

    // 2. cap(a) = 3  double = 6  cap(b) = 7 > double ==> cap(b) = 7 ==> roundup +1 => cap(b) = 8
    b2 := append(a, 4, 5, 6, 7)
    fmt.Printf("cap(a)=%v,cap(b2)=%v\n", cap(a), cap(b2))

    // 测试1024
    c := make([]int, 1024, 1024)
    fmt.Printf("cap(c)=%v,len(c)=%v\n", cap(c), len(c))
    d := append(c, 1)
    // 3. len(c) = 1024 , double = 1024 + 1024 / 4 = 1280  cap(d) = 1025 < double => cap(d) = double = 1280
    fmt.Printf("cap(c)=%v,cap(d)=%v\n", cap(c), cap(d))

    c1 := make([]int, 10, 1024)
    fmt.Printf("cap(c1)=%v,len(c1)=%v\n", cap(c1), len(c1))
    d1 := append(c1, 1)
    // 4. 没有触发cap增长。
    fmt.Printf("cap(c1)=%v,cap(d1)=%v\n", cap(c1), cap(d1))
    // fmt.Println(d1)  // [0 1 0 0 0 0 0 0 0 0 1]

    // 5. 制造cap小于doublecap。
    c2 := make([]int, 1023, 1024)
    fmt.Printf("cap(c2)=%v,len(c2)=%v\n", cap(c2), len(c2))
    d2 := append(c2, 1, 2, 4)
    // 5. 这里虽然cap(c2) = 1024 但是len(c2) < 1024 => double = 2 * 1024  cap(d2) = 1025 < 2048 => cap(d2) = 2048
    fmt.Printf("cap(c2)=%v,cap(d2)=%v\n", cap(c2), cap(d2))


    // 5. cap小于doublecap。
    c3 := make([]int, 1023, 1026)
    fmt.Printf("cap(c2)=%v,len(c2)=%v\n", cap(c3), len(c3))
    d3 := append(c3, 1, 2, 4, 5)
    // cap(c3) = 1025 len(c3) = 1023 < 1024 => double = 2 * 1025  cap(d2) = 1025 < 2050 => 归一化到2^x = 2304 ... 神奇
        // roundupsize 这个方法对于1024 < size <  32768 的数据进行了分段的映射。 应该是为了避免 内存的碎片化 ... 
    fmt.Printf("cap(c2)=%v,cap(d2)=%v\n", cap(c3), cap(d3))

}

还是很复杂的呢。

相关文章

  • golang slice的误解

    slice的介绍: 在golang的官方文档中,我们发现golang除了有array的数据还有一个slice,而a...

  • golang 切片小结

    golang slice

  • golang中的slice

    上文讲解了数组这篇文章主要讲解Slice(切片)。Slice代表变长的序列,其里面的每个元素都有相同的类型。Sli...

  • golang中的slice

    上面这段代码神奇的地方就是 注释的部分。 其原因可以参考这篇文章 https://tiancaiamao.gitb...

  • golang删除数组某个元素

    golang中对一个slice进行“slice”可以取片段得到一个新的slice,那么如何用简洁的代码删除slic...

  • Golang 中的数组 (array) 和切片 (slice)

    huangwenwei - 字里行间 | Golang 中的数组 (array) 和切片 (slice) 中文描述...

  • golang 删除 slice 中的部分元素

    golang 对 slice 的操作全在 [:] 中 和 append Noticesslice[A:B], 包涵...

  • 我设计的golang面试题

    1 golang中的引用类型 ``` slice、map、channel、interface ``` 2、map如...

  • golang中slice转化

    首先golang中确实没有提供引用的编程符号(c++ 中有&,建议可以先简单了解c++的引用)参考 疑问1 编译不...

  • golang 中神奇的 slice

    声明:本文仅限于简书发布,其他第三方网站均为盗版,原文地址: golang 中神奇的 slice 在 golang...

网友评论

      本文标题:golang中的slice

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