厚土Go学习笔记 | 19. slice和数组很像,但是slice可以添加元素

slice中文可以称为“切片”。是Go语言为处理同类型数据序列提供的一个高效且方便的方式。是在数组上抽象的一个数据类型。

切片的使用相当的广泛。

切片可以直接赋值,不用提前指定元素的个数。切片还可以动态的增加元素。 一个slice也就是切片的声明是这样的

s := []int{1,1,2,3,5,8,13,21,34}

也可以使用make创建,make创建slice时需要指定元素个数。

a := make([]int,0)

先指定为0个

package main

import (
    "fmt"
)

func main() {
    s := []int{1,1,2,3,5,8,13,21,34}
    a := make([]int,0)

    fmt.Println(s)
    fmt.Println(a)
}

运行结果如下

[1 1 2 3 5 8 13 21 34]
[]

slice添加元素是这样写的

a = append(a, 55, 89)

这个append给slice a添加了2个整数。但是,其实 = 左边和右边的a并不是同一个a了。

为了验证这两个a已经发生了根本的变化,我们来取得append前后a的内存地址做比较。

不过,因为我们之前声明a的时候,没有给a元素个数,那么它那个时候还没有分配内存。我们先修改一下

a := make([]int,0)
// 修改为
a := make([]int,1)

看一下代码示例

package main

import (
    "fmt"
)

func main() {
    s := []int{1,1,2,3,5,8,13,21,34}
    a := make([]int,1)

    fmt.Println(s)
    fmt.Println(a)

    fmt.Println(&a[0])
    a = append(a, 55, 89)
    fmt.Println(a)
    fmt.Println(&a[0])
}

运行的结果是这样的

[1 1 2 3 5 8 13 21 34]
[0]
0xc0420361d0
[0 55 89]
0xc04203c480

注意输出的运行结果中[0 55 89]前后两个地址的不同。当然,在你的机器上的地址很可能与我的不同,那是因为每次运行时,环境不同就可能有不同的内存分配过来。

既然两个a是不同的变量(因为a的内存地址会发生变化,通过地址访问会掉入逻辑错误的坑里),那么,下面的代码就容易理解了。

b := make([]int, 0)
b = append(a, 144)
fmt.Println(&b[0])

然后你再给 b = append()增加一个元素看看效果。然后再减掉刚增加的这个看看有什么变化。

b := make([]int, 0)
b = append(a, 144, 233)
fmt.Println(&b[0])

是的,看到了b的内存地址的变化了。这是因为原来的slice对应的容量不够了,随着slice元素的增加,又重新分配了内存地址。

所以,这里有一个结论,slice在内存中保存的位置并不是稳定,没什么必要的话,不要用内存地址或者指针玩slice,小心有坑。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2017-12-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏柠檬先生

jquery mobile 移动web(5)

有序列表   <div data-role="content">     <ol data-role="listview" data-theme="...

22150
来自专栏十月梦想

Vue组件参数校验和props特性

其实我们可以在组件中把这个props换成一个对象,看到上述代码,type可以为一个数组,来判断这个传递的数据的类型,不符合则报错,required表示这个参数必...

21610
来自专栏web前端教室

WEB前端零基础课-1022本周总结

v-if,根据true或是false,来决定是否插入到页面当中,dom节点,不在页面中

11510
来自专栏iKcamp

React 深入系列3:Props 和 State

文:徐超,《React进阶之路》作者 授权发布,转载请注明作者及出处 ---- React 深入系列3:Props 和 State React 深...

40360
来自专栏Python小屋

Python使用标准库subprocess调用外部程序

Python标准库subprocess中提供了很多调用外部程序创建子进程的对象,本文重点演示Popen对象的stdin和stdout属性的用法。 假设有一个程...

412100
来自专栏企鹅号快讯

不到200行 JavaScript 代码如何实现富文本编辑器

作者:吴锴 http://www.wukai.me/2017/12/31/rich-text-editor-in-less-than-200-lines-jav...

23270
来自专栏遊俠扎彪

Makefile中的Shell脚本简介

1、Makefile中可以嵌入shell脚本,而且能像shell脚本中一样,各种命令、控制结构都可使用。

21980
来自专栏轮子工厂

课后习题答案

这个是一个很经典的 C 语言入门编程题,可以通过刚刚所讲的循环嵌套来实现,如果将每个表达式看成 i * j,那么第一行是 i = 1,j <= i,第二行是i ...

14810
来自专栏web前端教室

[视频直播]本周日先行者视频“React多级菜单

第一个知识点,就是递归。 递归往简单了说,就是函数不断调用自身,同时设定一个退出条件,达成条件就结束调用自身,否则就成无限递归了。 看一小段JSON: { ...

23190
来自专栏iOSer成长记录

iOS-自定义TextField(解决输入限制,键盘弹出问题)

16020

扫码关注云+社区

领取腾讯云代金券