5.Go 语言数据类型:数组与切片

Python编程时光 · · 397 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Hi,大家好。

我是明哥,在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不防关注一下,一起学习,一起成长。

我的在线博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime

1. 数组

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。因为数组的长度是固定的,所以在Go语言中很少直接使用数组。

声明数组,并给该数组里的每个元素赋值(索引值的最小有效值和其他大多数语言一样是 0,不是1)

// [3] 里的3 表示该数组的元素个数 
var arr [3]int
arr[0] = 1
arr[1] = 2
arr[2] = 3

声明并直接初始化数组

// 第一种方法
var arr [3]int = [3]int{1,2,3}

// 第二种方法
arr := [3]int{1,2,3}

上面的 3 表示数组的元素个数 ,万一你哪天想往该数组中增加元素,你得对应修改这个数字,为了避免这种硬编码,你可以这样写,使用 ... 让Go语言自己根据实际情况来分配空间。

arr := [...]int{1,2,3}

[3]int[4]int 虽然都是数组,但他们却是不同的类型,使用 fmt 的 %T 可以查得。

import (
    "fmt"
)

func main() {
    arr01 := [...]int{1, 2, 3}
    arr02 := [...]int{1, 2, 3, 4}
    fmt.Printf("%d 的类型是: %T\n", arr01, arr01)
    fmt.Printf("%d 的类型是: %T", arr02, arr02)
}

输出 如下

[1 2 3] 的类型是: [3]int
[1 2 3 4] 的类型是: [4]int

如果你觉得每次写 [3]int 有点麻烦,你可以为 [3]int 定义一个类型字面量,也就是别名类型。

使用 type 关键字可以定义一个类型字面量,后面只要你想定义一个容器大小为3,元素类型为int的数组 ,都可以使用这个别名类型。

import (
    "fmt"
)

func main() {
    type arr3 [3]int

    myarr := arr3{1,2,3}
    fmt.Printf("%d 的类型是: %T", myarr, myarr)
}

输出 如下

[1 2 3] 的类型是: main.arr3

2. 切片

切片(Slice)与数组一样,也是可以容纳若干类型相同的元素的容器。与数组不同的是,无法通过切片类型来确定其值的长度。每个切片值都会将数组作为其底层数据结构。我们也把这样的数组称为切片的底层数组。

切片是对数组的一个连续片段的引用,所以切片是一个引用类型,这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内(意思是这是个左闭右开的区间)

import (
    "fmt"
)

func main() {
    myarr := [...]int{1, 2, 3}
    fmt.Printf("%d 的类型是: %T", myarr[0:2], myarr[0:2])
}

输出 如下

[1 2] 的类型是: []int

切片的构造,有三种方式

  1. 对数组进行片段截取(上面例子已经展示:myarr[0:2],0是索引起始值,2是索引终止值,区间左半右开)
  2. 从头声明赋值(例子如下)

    // 声明字符串切片
    var strList []string
    
    // 声明整型切片
    var numList []int
    
    // 声明一个空切片
    var numListEmpty = []int{}
  3. 使用 make 函数构造,make 函数的格式:make( []Type, size, cap )

    这个函数刚好指出了,一个切片具备的三个要素:类型(Type),长度(size),容量(cap)

    import (
        "fmt"
    )
    
    func main() {
        a := make([]int, 2)
        b := make([]int, 2, 10)
        fmt.Println(a, b)
        fmt.Println(len(a), len(b))
        fmt.Println(cap(a), cap(b))
    }

    输出 如下

    [0 0] [0 0]
    2 2
    2 10

关于 len 和 cap 的概念,可能不好理解 ,这里举个例子:

  • 公司名,相当于字面量,也就是变量名。
  • 公司里的所有工位,相当于已分配到的内存空间
  • 公司里的员工,相当于元素。
  • cap 代表你这个公司最多可以容纳多少员工
  • len 代表你这个公司当前有多少个员工

由于 切片是引用类型,所以你不对它进行赋值的话,它的零值(默认值)是 nil

var myarr []int
fmt.Println(myarr == nil)
// true

数组 与 切片 有相同点,它们都是可以容纳若干类型相同的元素的容器

也有不同点,数组的容器大小固定,而切片本身是引用类型,它更像是 Python 中的 list ,我们可以对它 append 进行元素的添加。

import (
    "fmt"
)

func main() {
    myarr := []int{1}
    // 追加一个元素
    myarr = append(myarr, 2)
    // 追加多个元素
    myarr = append(myarr, 3, 4)
    // 追加一个切片, ... 表示解包,不能省略
    myarr = append(myarr, []int{7, 8}...)
    // 在第一个位置插入元素
    myarr = append([]int{0}, myarr...)
    // 在中间插入一个切片(两个元素)
    myarr = append(myarr[:5], append([]int{5,6}, myarr[5:]...)...)
    fmt.Println(myarr)
}

输出 如下

[0 1 2 3 4 5 6 7 8]

最后,给你留一道思考题,如下 这段代码

import (
    "fmt"
)

func main() {
    var numbers4 = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    myslice := numbers4[4:6:8]
    fmt.Printf("myslice为 %d, 其长度为: %d\n", myslice, len(myslice))

    myslice = myslice[:cap(myslice)]
    fmt.Printf("myslice的第四个元素为: %d", myslice[3])
}

为什么 myslice 的长度为2,却能访问到第四个元素

myslice为 [5 6], 其长度为: 2
myslice的第四个元素为: 8

系列导读

01. 开发环境的搭建(Goland & VS Code)

02. 学习五种变量创建的方法

03. 详解数据类型:整形与浮点型

04. 详解数据类型:byte、rune与string

05. 详解数据类型:数组与切片

06. 详解数据类型:字典与布尔类型

07. 详解数据类型:指针

08. 面向对象编程:结构体与继承

09. 一篇文章理解 Go 里的函数

10. Go语言流程控制:if-else 条件语句

11. Go语言流程控制:switch-case 选择语句

12. Go语言流程控制:for 循环语句

13. Go语言流程控制:goto 无条件跳转

14. Go语言流程控制:defer 延迟调用

15. 面向对象编程:接口与多态

16. 关键字:make 和 new 的区别?

17. 一篇文章理解 Go 里的语句块与作用域

18. 学习 Go 协程:goroutine

19. 学习 Go 协程:详解信道/通道

20. 几个信道死锁经典错误案例详解

21. 学习 Go 协程:WaitGroup

22. 学习 Go 协程:互斥锁和读写锁

23. Go 里的异常处理:panic 和 recover

24. 超详细解读 Go Modules 前世今生及入门使用

25. Go 语言中关于包导入必学的 8 个知识点

26. 如何开源自己写的模块给别人用?

27. 说说 Go 语言中的类型断言?

28. 这五点带你理解Go语言的select用法



有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:Python编程时光

查看原文:5.Go 语言数据类型:数组与切片

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

397 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传