GO语言复合类型03---切片
切片相当于长度可以动态扩张的数组
array[start:end]从数组身上截取下标为[start,end)片段,形成切片
start代表开始下标,不写默认代表从头开始切
end代表结束下标(本身不被包含),不写默认截取到末尾
func main041() {
var array = [10]int{0, 11, 22, 33, 44, 55, 66, 77, 88, 99}
//含头不含尾,从array的第0项截取到第9项
slice := array[0:10]
fmt.Printf("array的类型是%T,值是%v\n", array, array) //[10]int
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice) //
slice = array[0:5]
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice) //[]int
slice = array[2:5]
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice)//[]int [22 33 44]
slice = array[:5]
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice)//[]int [0 11 22 33 44]
slice = array[2:]
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice)//[]int [22 33 44 55 66 77 88 99]
slice = array[:]
fmt.Printf("slice的类型是%T,值是%v\n", slice, slice)//[]int [0 11 22 33 44 55 66 77 88 99]
//也可以对切片进行截取,得到切片
sonSlice := slice[:]
fmt.Printf("sonSlice的类型是%T,值是%v\n", sonSlice, sonSlice)//[]int [0 11 22 33 44 55 66 77 88 99]
}
向切片中追加元素&遍历切片
func main042() {
//初始化一个没有元素的整型切片
var slice []int = []int{}
fmt.Printf("类型是%T\n", slice) //[]int
fmt.Printf("切片的长度是%d,值是%v\n", len(slice), slice) //0,[]
slice = append(slice, 0)
fmt.Printf("切片的长度是%d,值是%v\n", len(slice), slice) //1,[0]
slice = append(slice, 11, 22, 33)
fmt.Printf("切片的长度是%d,值是%v\n", len(slice), slice) //4,[0 11 22 33]
//for i := 0; i < len(slice); i++ {
// fmt.Printf("slice的第%d个元素的值是%v\n", i, slice[i])
//}
for index, value := range slice {
fmt.Printf("slice的第%d个元素是%v\n", index, value)
}
}
cap(slice)获得切片的容量
创建之初,容量等于长度
扩张时,一旦容量无法满足需要,就以翻倍的策略扩容
func main043() {
var slice = []int{1, 2, 3} //len=3,cap=3
slice = append(slice, 4)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=4 cap=6
slice = append(slice, 1)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=5 cap=6
slice = append(slice, 2)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=6 cap=6
slice = append(slice, 3)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=7 cap=12
slice = append(slice, 4)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=8 cap=12
slice = append(slice, 5)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=9 cap=12
slice = append(slice, 6)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=10 cap=12
slice = append(slice, 7)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=11 cap=12
slice = append(slice, 8)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=12 cap=12
slice = append(slice, 9)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=13 cap=24
slice = append(slice, 10)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=14 cap=24
slice = append(slice, 11, 12, 13, 14, 15, 16)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=20 cap=24
slice = append(slice, 17)
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=21 cap=24
for i := 18; i < 33; i++ {
slice = append(slice, i)
}
fmt.Printf("slice的长度是%d,容量是%d\n", len(slice), cap(slice))//len=36 cap=48
}
兼并另一个切片
func main044() {
var slice1 = []int{1, 2, 3} //len=3,cap=3
slice2 := []int{5, 6, 7, 8}
//slice1兼并slice2
//for _, value := range slice2 {
// slice1 = append(slice1, value)
//}
slice1 = append(slice1, slice2...)
fmt.Println(slice1)
}
创建指定长度和容量的切片
func main045() {
//var slice []int = []int{3,1,4,1,5}
//创建长度为3的整型切片
//slice := make([]int, 3)
//创建长度为3、容量为5的整型切片
slice := make([]int, 3, 5)
fmt.Println(slice)
fmt.Println(len(slice), cap(slice))
slice = append(slice, 4, 5)
fmt.Println(slice,len(slice), cap(slice))//[0 0 0 4 5] 5 5
slice = append(slice, 4, 5)
fmt.Println(slice,len(slice), cap(slice))//[0 0 0 4 5 4 5] 7 10
}
扩容策略:容量不够时,容量*2(有时+2),找到一片新的连续内存,将原有元素拷贝过去
func main046() {
//创建一个0长度(容量默认和长度一样)的整型切片
slice := make([]int, 0)
fmt.Println(slice, len(slice), cap(slice)) //[],0,0
slice = append(slice, 1)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=", slice,"首元素地址 =",&slice[0]) //1,1,[1]
slice = append(slice, 2)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0],&slice[1])//2,2,[1 2],地址变化
slice = append(slice, 3)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0],&slice[1])//3,4,[1 2 3],地址变化
slice = append(slice, 4)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//4,4,[1 2 3 4]
slice = append(slice, 5)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//5,8,[1 2 3 4 5],地址变化
slice = append(slice, 6,7)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//7,8,[1 2 3 4 5 6 7]
slice = append(slice, 8,9,10)
fmt.Println("len=",len(slice),"cap=",cap(slice),"s=",slice,"首元素地址 =",&slice[0])//10,16,[1 2 3 4 5 6 7 8 9 10],地址变化
}
切片扩容的一刹那,所有元素的地址都重新拷贝到了一片新的连续内存中
func main047() {
var array = [5]int{0, 1, 2, 3, 4}
//切片不是拷贝,而是地址引用
slice1 := array[:]
slice2 := slice1[:]//len=5,cap=5
//array,slice1,slice2的具有完全相同的元素初始地址
//fmt.Printf("%p,%p,%p\n", &array, &slice1, &slice2)//各不相同(栈内存)
fmt.Printf("%p,%p,%p\n", &array[0], &slice1[0], &slice2[0])//相同
fmt.Printf("%p,%p,%p\n", &array[1], &slice1[1], &slice2[1])//相同
//牵一发而动全身
array[1] = 11
slice1[2] = 222
slice2[3] = 3333
fmt.Println(array) //[0,11,222,3333,4]
fmt.Println(slice1) //[0,11,222,3333,4]
fmt.Println(slice2) //[0,11,222,3333,4]
//slice2扩容之后,所有元素的地址都发生了迁移(拷贝了一份)
slice2 = append(slice2, 5,6,7)
array[0] = 10
slice1[1] = 111
slice2[0] = 1000
fmt.Println(array) //[10,111,222,3333,4]
fmt.Println(slice1) //[10,111,222,3333,4]
fmt.Println(slice2) //[1000,11,222,3333,4]
fmt.Printf("cap2=%d\n",cap(slice2))
fmt.Printf("%p,%p,%p\n", &array[0], &slice1[0], &slice2[0])//相同
}
GO语言复合类型03---切片的更多相关文章
- GO语言复合类型04---映射
package main import "fmt" /* 映射(map)是键值对(key-value)数据的集合 根据键key可以快速检索值value 键值的类型可以是任意的,ke ...
- GO语言复合类型02---数组
package main import "fmt" /* 固定长度.固定类型的数据容器 */ /*数组的声明*/ func main031() { //var array [5]i ...
- GO语言复合类型01---指针
package main /* %T 类型占位符 %v 值占位符 %p 地址(指针)占位符,只有地址才能替换%p &value 对值取地址 *addr 对地址取值 **int 指向int型指针 ...
- GO语言复合类型05---递归
package main import ( "fmt" "time" ) /* ·递归就是自己调自己 ·递归一定要有终止条件(否则就是无限死循环) */ /*使 ...
- go语言 类型:基础类型和复合类型
Go 语言中包括以下内置基础类型:布尔型:bool整型:int int64 int32 int16 int8 uint8(byte) uint16 uint32 uint64 uint浮点型:floa ...
- 带你学够浪:Go语言基础系列 - 8分钟学复合类型
★ 文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) " 对于一般的语言使用者来说 ,20% ...
- [Go] 复合类型(数组、切片、字典、结构体)变量的 初始化 及 注意事项
Go变量 初始化 对 复合类型(数组.切片.字典.结构体)变量的初始化是,有一些语法限制: 1.初始化表达式必须包含类型标签: 2.左花括号必须在类型尾部,不能另起一行: 3.多个成员初始值以逗号分隔 ...
- go语言入门(6)复合类型
1,分类 2,指针 指针是一个代表着某个内存地址的值.这个内存地址往往是在内存中存储的另一个变量的值的起始位置. 1)基本操作 Go语言虽然保留了指针,但与其它编程语言不同的是: 默认值 nil,没有 ...
- 学习Golang语言(6):类型--切片
学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Gola ...
随机推荐
- 脱壳——修复加密IAT
脱壳--修复加密IAT 对两个练手程序进行脱壳修复加密IAT(其实是一个程序,只是用了几种不同的加壳方式) 第一个程序 Aspack.exe 下载链接:https://download.csdn.ne ...
- 记一次linux下安装ftp的愉快体验
三三两两,试了几次就出来了,挺开心的 linux安装vsftpd,请自行百度 贴出部分配置点 阿里云服务器,开发相关端口以及部分区域端口访问 /etc/pad.d/vsftpd添加部分注释 #%PAM ...
- php 简易日志函数应用 debug_backtrace()
1 public static function writeILogs($datas) 2 { 3 $bt = debug_backtrace(); 4 $caller = array_shift($ ...
- 【网络协议】 TCP三次握手的流程
在TCP/IP协议中,TCP协议通过三次握手,建立可靠的连接服务: 三次握手是由客户端发起 第一步: 客户端向服务端发送请求报文(实际上就是一个具有特定格式的数据包),报文中包含一个标志为Syn,Sy ...
- POJ2135 来回最短路(简单费用流)
题意: 就是从1走到n然后再走回来,一条边只能走一次,要求路径最短. 思路: 比较水,可以直接一遍费用流,不解释了,具体的看看代码,敲这个题就是为了练 练手,好久不敲了,怕比赛 ...
- android安全学习、工具库、框架
在介绍android工具之前,先理清android中出现的文件格式: java:android源码 class:java编译后生成: dex: 由dx工具编译class而成,由dalvik执行: sm ...
- 将大量ASCII码值转换成字符函数CHR()的小技巧
一.在学习命令执行漏洞的过程中,遇到以下情况: 当服务器上传不了马或者马被过滤的时候,我们可以迂回一下,通过执行写马命令到服务器,在服务器里面写马,该命令是通过ascii编码过的命令,防止被过滤. 1 ...
- Day007 计算器
计算器 public static void main(String[] args) { double[] num={0,1}; String oprater="a"; doubl ...
- 【vue-08】vuex
vuex的作用 简单理解,就是将多个组件共享的变量统一放到一个地方去管理,比如用户登录时的数据token. 快速上手 安装:npm install vuex 首先,我们在src文件夹下创建一个文件夹: ...
- 【实用小技巧】spring springmvc集成shiro时报 No bean named 'shiroFilter' available
查了网上的,很多情况,不同的解决办法,总归一点就是配置文件加载的问题. 先看下配置文件中的配置 web.xml中的主要配置(这是修改后不在报错的:仅仅修改了一个位置:[classpath:spring ...