失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 四 Go语言复合数据类型(上)

四 Go语言复合数据类型(上)

时间:2021-10-13 16:32:14

相关推荐

四 Go语言复合数据类型(上)

@Author:Runsen

复合数据类型主要包含Go中的一些复杂类型,主要有指针类型,数组类型,切片类型,结构体类型,Map类型和Channel类型

文章目录

指针数组切片

指针

相信大家都在在C语言听过指针。首先指针是一个变量,全名叫做指针变量,只不过这个变量里面存储的值是一个地址而已。所以指针,哪怕是空指针,都是有地址的,因为变量都是有地址的。

变量其实是一种使用方便的占位符,引用计算机中的内存地址。指针其实也就是把某个变量指向到特定内存地址,类似于Linux中的软链概念。

不用单独开辟出一块内存用于存储,而是把新变量的实际内存指向到已占有内存空间的现变量中。Go语言中取变量地址符用&,声明一个指针类型用*,比如声明一个int型的指针类型

下面举一个例子,代码如下:

package mainimport "fmt"func main() {var a * intfmt.Printf("&a: %v, a:%v \n",&a,a) b := 1fmt.Printf("&b: %v, b:%v \n",&b,b) a = &bfmt.Printf("&a: %v, a:%v \n",&a,a) fmt.Printf("&b: %v, b:%v \n",&b,b) }&a: 0xc000006028, a:<nil> &b: 0xc0000120f0, b:1 &a: 0xc000006028, a:0xc0000120f0 &b: 0xc0000120f0, b:1

从输出我们可以看到空指针a的地址是存在,在a指向b之前,指针a的值为nil,指向b之后,数值变成了变量b的地址,而对a 做操作*a的话,数值为变量b对应的数值1。

数组

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列。

格式规则为:var variable_name [SIZE] variable_type

比如定义一个长度为3,类型是int的数组:var a [3]int

注意:长度必须是常量,它是数组类型的一部分,一旦定义,长度不能改变。

初始化数组时可以使用初始化列表来设置数组元素的值,具体如下面的代码所示。

package mainimport "fmt"func main() {var testArray [3]int //数组会初始化为int类型的零值var numArray = [3]int{1, 2} //使用指定的初始值完成初始化var cityArray = [3]string{"北京", "上海", "广州", "深圳"} //使用指定的初始值完成初始化fmt.Println(testArray) //[0 0 0]fmt.Println(numArray) //[1 2 0]fmt.Println(cityArray) //[北京 上海 广州 深圳]// 我们还可以使用指定索引值的方式来初始化数组,例如:a := [...]int{1: 1, 3: 5}fmt.Println(a) // [0 1 0 5]}

数组的遍历有两种方法,分别是for range和通过索引遍历。

package mainimport "fmt"func main() {var a = [...]string{"北京", "上海", "广州", "深圳"}// 通过索引遍历数组for i := 0; i < len(a); i++ {fmt.Println(a[i])}fmt.Println("================")// 用for range遍历数组for _, v := range a {fmt.Println(v)}}

其实多维数组和一维数组定义完全相同:var 数组名 [数组大小][数组大小]类型

下面我们定义一个二维数组,具体代码如下。

package mainimport "fmt"func main() {var cities = [3][2]string{{"北京", "上海"},{"广州", "重庆"},{"深圳", "东莞"},}fmt.Println(cities) //[[北京 上海] [广州 重庆] [深圳 东莞]]fmt.Println(cities[0][0]) //北京}

切片

因为Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,于是Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大,这个就是切片。

声明一个未指定大小的数组来定义切片:var identifier []type。因此,切片不需要说明长度。

很多人使用make()函数来创建切片:,具体如下。

var slice1 []type = make([]type, len)// 也可以简写为slice1 := make([]type, len)

切片是可索引的,并且可以由 len() 方法获取长度。

切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

下面我们具体使用下切片,具体代码如下。

package mainimport "fmt"func main(){var numbers = make([]int,3,5)// 两个代码相同// umbers := make([]int, 3,5)fmt.Printf("len=%d, cap=%d, slice=%v\n",len(numbers),cap(numbers),numbers) //len=3, cap=5, slice=[0 0 0]}

切片截取是通过设置下限及上限来设置截取切片[lower-bound:upper-bound],具体实例如下:

package mainimport "fmt"func printSlice(x []int){fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)}func main() {/* 创建切片 */numbers := []int{0,1,2,3,4,5,6,7,8,9} printSlice(numbers)/* 打印原始切片 */fmt.Println("numbers ==", numbers)/* 打印子切片从索引1(包含) 到索引4(不包含)*/fmt.Println("numbers[1:4] ==", numbers[1:4])/* 默认下限为 0*/fmt.Println("numbers[:3] ==", numbers[:3])/* 默认上限为 len(s)*/fmt.Println("numbers[4:] ==", numbers[4:])numbers1 := make([]int,0,5)printSlice(numbers1)/* 打印子切片从索引 0(包含) 到索引 2(不包含) */number2 := numbers[:2]printSlice(number2)/* 打印子切片从索引 2(包含) 到索引 5(不包含) */number3 := numbers[2:5]printSlice(number3)}

执行以上代码输出结果为:

len=10 cap=10 slice=[0 1 2 3 4 5 6 7 8 9]numbers == [0 1 2 3 4 5 6 7 8 9]numbers[1:4] == [1 2 3]numbers[:3] == [0 1 2]numbers[4:] == [4 5 6 7 8 9]len=0 cap=5 slice=[]len=2 cap=10 slice=[0 1]len=3 cap=8 slice=[2 3 4][Finished in 1.3s]

如果觉得《四 Go语言复合数据类型(上)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。