前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言的复合数据类型

Go语言的复合数据类型

作者头像
李海彬
发布2018-03-27 15:26:20
6370
发布2018-03-27 15:26:20
举报
文章被收录于专栏:Golang语言社区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 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档