设为首页 加入收藏

TOP

Go语言中slice使用注意事项(二)
2017-11-01 06:07:09 】 浏览:499
Tags:言中 slice 使用 注意事项
//a: [10 1] &a[0]: 0x10410020 len: 2 cap: 4 fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a)) //b: [10 1] &b[0]: 0x10410020 len: 2 cap: 4 fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b)) }

示例代码  https://play.golang.org/p/Efb42G5Wt9
如上所示,若append后的b的实际元素个数没有超过原来的a指向的底层数组的容量,那么a,b指向同一个底层数组。
注意此时append的操作对象是:对a进行切分之后的切片,只取了a的第一个值,相当于一个新切片,长度为1,和a指向同一个底层数组,我们称这个切分后的新切片为c吧,那么就相当于b其实是基于c切片进行append的,直接在长度1之后追加元素,所以append之后a的第二个元素变成了1。【所以切分操作和append操作放一起的时候,一定要小心】 
 
第四种情况:
func main() {

    a := make([]int, 2, 4)
    a[0] = 10
    a[1] = 20
    //a: [10 20]       &a[0]: 0x10410020  len: 2  cap: 4
    fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))

    //进行append操作
    //append是在第一个元素后开始追加,所以要超过容量,至少要追加4个,而不是之前例子的3个
    b := append(a[:1], 1, 2, 3, 4)

    //a: [10 20]       &a[0]: 0x10410020  len: 2  cap: 4
    fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))
    
    //b: [10 1 2 3 4]  &b[0]: 0x10454020  len: 5  cap: 8
    fmt.Println("b:", b, " &b[0]:", &b[0], " len:", len(b), " cap:", cap(b))
}

示例代码  https://play.golang.org/p/wzNbO9vDJ0
如上所示,这种情况主要用来与第三种情况对比,如果append的元素数较多,超过了原来的容量,直接采用了新的底层数组,也就不会影响到a了。 
 
上述的四种情况所用例子都比较简单,所以比较容易看清。要小心如果在函数间传递slice,调用函数采用append进行操作,可能会改变原来的值的,如下所示:
func main() {

    a := make([]int, 2, 4)
    a[0] = 10
    a[1] = 20
    //a: [10 20]  &a[0]: 0x10410020  len: 2  cap: 4
    fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))

    testAppend(a[:1])

    //a: [10 1]   &a[0]: 0x10410020  len: 2  cap: 4
    fmt.Println("a:", a, " &a[0]:", &a[0], " len:", len(a), " cap:", cap(a))

}

func testAppend(s []int) {
    //进行append操作
    s = append(s, 1)
    //s: [10 1]  &s[0]: 0x10410020  len: 2  cap: 4
    fmt.Println("s:", s, " &s[0]:", &s[0], " len:", len(s), " cap:", cap(s))
}

示例代码 https://play.golang.org/p/mvUZkmBW8u

 

参考资料 https://blog.golang.org/go-slices-usage-and-internals

 
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇为golua编译lua5.1 下一篇go 代码的调试---打印调用堆栈

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目