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

举报
毛利 发表于 2021/07/15 04:07:07 2021/07/15
【摘要】 @Author:Runsen 复合数据类型主要包含Go中的一些复杂类型,主要有指针类型,数组类型,切片类型,结构体类型,Map类型和Channel类型 文章目录 指针数组切片 指针 相信大家都在在C语言听过指针。首先指针是一个变量,全名叫做指针变量,只不过这个变量里面存储的值是一个地址而已。所以指针,哪怕是空指针,都是有地址的,因为变量都是有地址的。...

@Author:Runsen

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

文章目录

指针

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

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

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

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

package main

import "fmt"

func main() { var a * int fmt.Printf("&a: %v, a:%v \n",&a,a) b := 1 fmt.Printf("&b: %v, b:%v \n",&b,b) a = &b fmt.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 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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

数组

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列。
格式规则为:var variable_name [SIZE] variable_type

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

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

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

package main

import "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]
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

package main

import "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)
	}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

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

package main

import "fmt"

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

切片

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

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

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

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

  
 
  • 1
  • 2
  • 3

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

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

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

package main

import "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]
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

package main

import "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)

}



  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

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

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]

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。

原文链接:maoli.blog.csdn.net/article/details/107816368

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。