go语言学习(四):数组和切片
在go语言中,数组和切片都是集合类型,他们都是用来存储同一种类型的元素。
1.数组类型的长度是固定的,而切片类型的长度是可变长的。如下面代码声明一个长度为5的数组s1和长度为5的切片s2,
s1 := [5]int{1,2,3,4,5}s2 := []int{1,2,3,4,5}
但是s1是不可变的,而s2是可变的,可以增加元素,长度随着元素数量而增长。因此数组是一个值类型,而切片是一个引用类型。
2.切片的底层是一个数组,如下面代码:s3是s4的底层数组,
s3 := []int{1, 2, 3, 4, 5, 6, 7, 8}s4 := s3[3:6]fmt.Printf("The length of s4: %dn", len(s4))fmt.Printf("The capacity of s4: %dn", cap(s4))fmt.Printf("The value of s4: %dn", s4)
上面代码输出如下:
The length of s4: 3 The capacity of s4: 5 The value of s4: [4 5 6] 因为切片S4取值从数组S3的下标4开始到下标6(不包含),所以长度是3,容量是5
3.切片是可以扩容的,往切片中增加元素时,当切片容量不够时,切片会进行扩容。
如果扩容前切片容量小于1024,那扩展为原容量的2倍。
如果扩容前切片容量大于等于1024,那扩展为原容量的1.25倍,如果还不够,会再次扩展为原来的1.25倍。
如果追加元素太多,扩展为2倍还不够,会直接扩展为新的长度。
// 示例1。 s6 := make([]int, 0) fmt.Printf("The capacity of s6: %dn", cap(s6)) for i := 1; i <= 5; i++ { s6 = append(s6, i) fmt.Printf("s6(%d): len: %d, cap: %dn", i, len(s6), cap(s6)) } fmt.Println()
// 示例2。 s7 := make([]int, 1024) fmt.Printf("The capacity of s7: %dn", cap(s7)) s7e1 := append(s7, make([]int, 200)...) fmt.Printf("s7e1: len: %d, cap: %dn", len(s7e1), cap(s7e1)) s7e2 := append(s7, make([]int, 400)...) fmt.Printf("s7e2: len: %d, cap: %dn", len(s7e2), cap(s7e2)) s7e3 := append(s7, make([]int, 600)...) fmt.Printf("s7e3: len: %d, cap: %dn", len(s7e3), cap(s7e3)) fmt.Println()
// 示例3。 s8 := make([]int, 10) fmt.Printf("The capacity of s8: %dn", cap(s8)) s8a := append(s8, make([]int, 11)...) fmt.Printf("s8a: len: %d, cap: %dn", len(s8a), cap(s8a)) s8b := append(s8a, make([]int, 23)...) fmt.Printf("s8b: len: %d, cap: %dn", len(s8b), cap(s8b)) s8c := append(s8b, make([]int, 45)...) fmt.Printf("s8c: len: %d, cap: %dn", len(s8c), cap(s8c))
s1 := [5]string{"a","b","c","d","e"} fmt.Printf("S1:%sn", s1) s2 := s1[3:5] fmt.Printf("S2:%sn", s2)
上面代码的输出如下:
The capacity of s6: 0 s6(1): len: 1, cap: 1 s6(2): len: 2, cap: 2 s6(3): len: 3, cap: 4 s6(4): len: 4, cap: 4 s6(5): len: 5, cap: 8
The capacity of s7: 1024 s7e1: len: 1224, cap: 1280 s7e2: len: 1424, cap: 1696 s7e3: len: 1624, cap: 2048
The capacity of s8: 10 s8a: len: 21, cap: 22 s8b: len: 44, cap: 44 s8c: len: 89, cap: 96 因为操作系统内存对齐的原因,扩容后的切片并不能恰好成为原切片的2倍或1.25倍
4.当切片扩容时,原切片和底层数据并没有被替换,而且生成了一个新的底层数组和切片。
当切片无需扩容时,append函数会返回一个指向原底层数组的新切片,但是当需要扩容时,append函数返回一个指向新底层数组的新切片。
// 示例1。 a1 := [7]int{1, 2, 3, 4, 5, 6, 7} fmt.Printf("a1: %v (len: %d, cap: %d)n", a1, len(a1), cap(a1)) s9 := a1[1:4] //s9[0] = 1 fmt.Printf("s9: %v (len: %d, cap: %d)n", s9, len(s9), cap(s9)) for i := 1; i <= 5; i++ { s9 = append(s9, i) fmt.Printf("s9(%d): %v (len: %d, cap: %d)n", i, s9, len(s9), cap(s9)) } fmt.Printf("a1: %v (len: %d, cap: %d)n", a1, len(a1), cap(a1)) fmt.Println()
上面代码输出:
a1: [1 2 3 4 5 6 7] (len: 7, cap: 7) s9: [2 3 4] (len: 3, cap: 6) s9(1): [2 3 4 1] (len: 4, cap: 6) s9(2): [2 3 4 1 2] (len: 5, cap: 6) s9(3): [2 3 4 1 2 3] (len: 6, cap: 6) s9(4): [2 3 4 1 2 3 4] (len: 7, cap: 12) s9(5): [2 3 4 1 2 3 4 5] (len: 8, cap: 12) a1: [1 2 3 4 1 2 3] (len: 7, cap: 7)
参考:极客时间
- HDU----(4549)M斐波那契数列(小费马引理+快速矩阵幂)
- Centos系统修改时区
- zookeeper思考与总结1:在其它组件的作用及hdfs对比
- HDU----(4291)A Short problem(快速矩阵幂)
- Linux下删除指定文件之外的其他文件
- HDU----(2157)How many ways??(快速矩阵幂)
- 试试Linux下的ip命令
- hdu---(2604)Queuing(矩阵快速幂)
- centos7下卸载python后yum不能使用的恢复方法
- hdu---(5038)Grade(胡搞)
- shell生成随机字符的几种方法
- Python时间获取及转换
- spark streaming知识总结[优化]
- 让你真正明白spark streaming
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 短视频APP开发,简单计时功能
- LeetCode | 94.二叉树的中序遍历
- Druid 的整合
- LeetCode | 104.二叉树的最大深度
- Flutter 目录结构和项目资源
- iOS音视频接入- TRTC互动直播
- 【一天一大 lee】查找常用字符 (难度:简单) - Day20201014
- 金九银十准备换场地?对标腾讯T3的Android高级工程师面试大纲及时雨来了
- 【一天一大 lee】两两交换链表中的节点 (难度:中等) - Day20201013
- 【一天一大 lee】二叉搜索树的最小绝对差 (难度:简单) - Day20201012
- 有奖互动 | 腾讯云开发者社区 3 周年庆,我过生日,送你们礼物 ~
- 【一天一大 lee】分割等和子集 (难度:中等) - Day20201011
- 【一天一大 lee】寻找两个正序数组的中位数 (难度:困难) - Day20201003
- 【一天一大 lee】颜色分类 (难度:中等) - Day20201007
- 【一天一大 lee】树中距离之和 (难度:困难) - Day20201006