李海彬
Go语言的复合数据类型
关注作者
前往小程序,Get
更优
阅读体验!
立即前往
腾讯云
开发者社区
文档
建议反馈
控制台
登录/注册
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
搜索
搜索
关闭
发布
首页
学习
活动
专区
工具
TVP
最新优惠活动
返回腾讯云官网
李海彬
首页
学习
活动
专区
工具
TVP
最新优惠活动
返回腾讯云官网
社区首页
>
专栏
>
Go语言的复合数据类型
Go语言的复合数据类型
李海彬
关注
发布于 2018-03-27 15:26:20
680
0
发布于 2018-03-27 15:26:20
举报
文章被收录于专栏:
Golang语言社区
Go语言的复合数据类型是基础数据类型的组合,主要包括四个数组,切片(slice),map和结构体。 数组和结构体的大小是固定大小的,数组的元素类型是固定的,结构体的元素类型是不固定。 map和slice是动态的数据结构,它们将根据需求动态的增长。 数组 数组顾名思义就是同一类资源或者数据的集合。下面主要介绍对数组的操作: 数组的初始化 var arr [3]int //默认初始化0 var q [3]int = [3]int{1,2,3} q := [...]int{1,2,3} q := [...]int{90:-1}//key和value的赋值方式,下表90的值为-1,数组长度为91 复制代码 数组的访问 可以使用数组下标来访问数组中的元素。与C语言相同,数组下标从0开始,len(array)-1 则表示最后一个元素的下标。下面的示例遍历整型数组并逐个打印元素内容: q := [...]int{1, 2, 3, 4} for i, value := range q { fmt.Println(i, value) } 复制代码 数组可以直接进行比较,当数组内的元素都一样的时候表示两个数组相等。 arr1 := [3]int{1, 2, 3} arr2 := [3]int{1, 2, 3} arr3 := [3]int{1, 2, 4} fmt.Println(arr1 == arr2, arr1 == arr3) //true,false 复制代码 数组可以作为函数的参数传入,但由于数组在作为参数的时候,其实是进行了拷贝,这样在函数内部改变数组的值,是不影响到外面的数组的值得。 func ArrIsArgs(arr [4]int) { arr[0] = 100 } q := [...]int{1, 2, 3, 4} ArrIsArgs(q) 如果想要改变: func ArrIsArgs(arr *[4]int) { arr[0] = 100 } q := [...]int{1, 2, 3, 4} ArrIsArgs(&q) 但一般都是用切片来解决这个问题,而不是用数组。 切片 切片和数组很相似,只是它的长度并不是固定的,也就是定义的时候[ ]T内不需要指定长度。 数组和slice关系非常密切,一个slice可以访问数组的部分或者全部数据,而且slice的底层本身就是对数组的引用。 一个Slice由三部分组成:指针,长度和容量。内置的len和cap函数可以分别返回slice的长度和容量 首先我们来看slice的创建方式: 创建slice主要两种:1.基于数组创建。2.直接创建 基础数组创建: 数组arrVar和sliceVar里面的地址其实是一样的,也就是说如果你改变sliceVar里面的变量,那么arrVar里面的变量也会随之改变。 2.直接创建 可以使用内置的make()函数来创建。事实上还是会创建一个匿名的数组,只是不需要我们来定义。 对于为什么说slice其实和数组是一个地址那,看下面这张图: 3.动态的增减元素 前面说过,slice是可以动态扩展的。但slice的动态扩展是有代价的,也就是说如果在确定大小的前提下,最好是设置好slice的cap大小,看个经典的例子: 可以看到,当slice的的容量等于len的时候,cap是翻倍了。append的底层原理就是当slice的容量满了的时候,重新建立一块内存,然后将原来的数据拷贝到新建的内存。所以说容量的扩充是存在内存的建立和复制的。该过程将会影响到系统的运行速度。 append 也可以将两个slice拼接起来,但格式有所不同: 两个slice也可以直接进行内容的复制,copy函数: 4.作为形参使用 要想搞清楚slice我们需要看一下slice作为函数参数的使用方式,看一下下面的几个例子: eg1 的结果是[0 1 2 3 4 5 6 7],eg2的结果是[0 0 0 0 0 0 0 0]。来分析两个实例的不同,如果和你想的不一样,那么就证明你对slice的理解是有问题的(我也纠结了比较久o(╯□╰)o) 首先分析一下第一个用例TestSLice(myslice1[:0]),这个的意思其实就是将一个新的slice作为参数传给函数,新的slice指向的是myslice1的第0个元素的地址,这时候你可以测试一下myslice1[:0]这个东西的cap和len,数值分别为8和0,然后你在函数里面append的时候实际上是对新的slice进行了操作,但由于外面的函数的参数的slice和myslice1又是同一个地址,所以外面的数值是被改变了的。 再来分析第二个实例,第二个实例直接把myslice1传给了函数,这其实是复制了一个slice的,在函数里面append的时候当你的len大于cap值得时候,这时候返回的是一个新的地址。所以外面的变量是不会变化的。全是默认值0 那么我们想直接改变外面的slice怎么办?答案就是指针,在GO语言里面你想修改什么就传什么的指针。 对于SLICE的应用基本就可以到这里结束了,大家可以多测试一下Slice的使用。 在Go语言中,所有的函数参数都是值拷贝传入的,函数参数将不再是函数调用时的原始变量 map 在C++/java中,map 一般都是封装在库里面的,但在GO语言中map可以直接使用。作为Key-value的数据结构,map就是对哈希表的引用。 1.声明 var myMap map[string] PersonInfo myMap是声明的变量名,sting是对应的Key的类型,PeesonInfo是value的类型。 2.创建 创建map使用的是GO语言内置的make()来创建的。 创建一个容量固定的MAP 创建初始化MAP 3.元素的删除 对于map的元素的删除,可以采用内置的delete函数 如果你后面传入的key不存在,那么调用不会产生什么错误,但如果myMap是nil那么就会抛出异常了。 4.元素的查找 在map中传统的做法是: 1.声明一个变量为空 2.将map中获得的值保存到变量中 3.判断是否为空。 但这种做法过于复杂,可以采用下面的方式来实现: value,ok := myM ap["1234"] if ok{//代表找到了 //代码处理模块 } delete(myMap,"123") mymap1 := map[string]int{"hello": 1, "world": 2} myMap = make(map[string] Personinfo,100) myMap = make(map[string] Personinfo) func TestSLice3(myslice *[]int) { for i := 0; i < 8; i++ { *myslice = append(*myslice, i) } } myslice1 := make([]int, 0, 8) TestSLice3(&myslice1) func TestSLice(myslice []int) { for i := 0; i < 8; i++ { myslice = append(myslice, i) } } eg1: myslice1 := make([]int, 8, 8) TestSLice(myslice1[:0]) fmt.Println(myslice1) //结果是什么? eg2: myslice1 := make([]int, 8, 8) TestSLice(myslice1 ) fmt.Println(myslice1) //结果是什么哪? slice1 := []int{1, 2, 3, 4, 5} slice2 := []int{5, 4, 3} copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中 copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置 oldSlice := []int{1, 2, 3, 4, 5} oldSlice2 := []int{6, 7, 8, 9, 10} oldSlice = append(oldSlice, oldSlice2...) //必须加三个... func TestAppend() { var slice []int for i := 0; i < 10; i++ { slice = append(slice, i) fmt.Printf("%d cap = %d t%v\n", i, cap(slice), slice) } } output: 0 cap = 1 t[0] 1 cap = 2 t[0 1] 2 cap = 4 t[0 1 2] 3 cap = 4 t[0 1 2 3] 4 cap = 8 t[0 1 2 3 4] 5 cap = 8 t[0 1 2 3 4 5] 6 cap = 8 t[0 1 2 3 4 5 6] 7 cap = 8 t[0 1 2 3 4 5 6 7] 8 cap = 16 t[0 1 2 3 4 5 6 7 8] 9 cap = 16 t[0 1 2 3 4 5 6 7 8 9] myslice1 := make([ ]int,5)//创建一个元素个数5的slice,cap也是5 myslice2 := make([ ]int,5,10)//创建一个元素个数5的slice,cap是10 myslice3 := [ ]int{1,2,3,4}//创建一个元素个数为4的slice,cap是4 var slice []int //创建一个空的slice,cap和len都是0 arrVar := [4]int{1, 2, 3,4} sliceVar := arrVar[1:3]
本文参与
腾讯云自媒体同步曝光计划
,分享自微信公众号。
原始发表:2017-08-15,如有侵权请联系
cloudcommunity@tencent.com
删除
go
本文分享自
Golang语言社区
微信公众号,
前往查看
如有侵权,请联系
cloudcommunity@tencent.com
删除。
本文参与
腾讯云自媒体同步曝光计划
,欢迎热爱写作的你一起参与!
go
评论
登录
后参与评论
0 条评论
热度
最新
推荐阅读
LV.
文章
0
获赞
0
领券
问题归档
专栏文章
快讯文章归档
关键词归档
开发者手册归档
开发者手册 Section 归档
0
0
0
推荐