09【保姆级】-GO语言的数组
- 一、数组
-
- [1.1 数组定义](#1.1 数组定义)
- [1.2 数组的使用](#1.2 数组的使用)
- [1.3 数组的遍历](#1.3 数组的遍历)
- [1.4 数组的应用案例](#1.4 数组的应用案例)
- 二、切片
-
- [2.1 切片的介绍](#2.1 切片的介绍)
- [2.2 切片的原理](#2.2 切片的原理)
- [2.3 切片的三种使用](#2.3 切片的三种使用)
之前我学过C、Java、Python语言时总结的经验:
- 先建立整体框架,然后再去抠细节。
- 先Know how,然后know why。
- 先做出来,然后再去一点点研究,才会事半功倍。
- 适当的囫囵吞枣。因为死抠某个知识点很浪费时间的。
- 对于GO语言,切记遵守语法格式规则。(例如python语言、例如SpringBoot框架等)
解释:某些知识点,就是很难了解,那么先做出来,然后继续向前学习,可能在某个时间点我们就会恍然大悟。
一、数组
1.1 数组定义
数组可以存放多个同一类型数据。数组也是一种数据类型,在 Go 中,数组是值类型。
初始化的四种方式:
go
var arr01 [3]int = [3]int{1, 2, 3}
var arr02 = [3]int{1, 2, 3}
var arr03 = [...]int{1, 2, 3}
var arr04 = [...]int{1: 111, 0: 001, 2: 222}
fmt.Println("arr04=", arr04) // arr04= [1 111 222]
// 设置排序顺序
数组的首地址 也就是 数组第一个元素的地址。第二个元素的地址是:首地址+数组类型的占用的字节数。
go
var arr [5]float64
fmt.Printf("首地址是:%p,首元素地址是:%p,第二个元素的地址是:%p", &arr, &arr[0], &arr[1])
// 首地址是:0xc042076030,首元素地址是:0xc042076030,第二个元素的地址是:0xc042076038
1.2 数组的使用
go
func main() {
var arr [5]float64
arr[0] = 1.2
arr[1] = 2.2
arr[2] = 21.2
arr[3] = 3.2
arr[4] = 4.2
num := 0.0
for i := 0; i < len(arr); i++ {
num += arr[i]
}
fmt.Println("num=", num) //n um= 32
}
1.3 数组的遍历
方式一常规方式:如上述章节方式
方式二:for-range结构遍历:用来遍历访问数组的元素
go
for index,value :=range array01{
}
- 第一个返回值 index是数组的下标
- 第二个value是在该下标位置的值
- 他们都是仅在for循环内部可见的局部变量
- 遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线_
- index和value 的名称不是固定的,即程序员可以自行指定,一般命名为index 和value
go
arr := [...]string{"张三", "lisi", "王五", "赵六"}
for i, s := range arr {
fmt.Println("元素索引是:", i, "元素是:", s)
}
元素索引是: 0 元素是: 张三
元素索引是: 1 元素是: lisi
元素索引是: 2 元素是: 王五
元素索引是: 3 元素是: 赵六
----
arr := [...]string{"张三", "lisi", "王五", "赵六"}
for _, s := range arr {
fmt.Println("元素是:", s)
}
元素是: 张三
元素是: lisi
元素是: 王五
元素是: 赵六
- 数组的下标是从0开始的。
- 数组下标必须在指定范围内使用,否则报 panic: 数组越界,比如var arr[5]int 则有效下标为 0-4
- Go的数组属值类型,在默认情况下是值传递, 因此会进行值拷贝。数组间不会相互影响
- 如想在其它函数中,去修改原来的数组,可以使用引用传递(指针方式)[先体验下,画示意图]
go
---值传递: 在test栈中会赋值arr的数据
func main() {
arr := [...]string{"11", "22", "33", "444"}
testArr(arr)
fmt.Println(arr) // [11 22 33 444]
}
func testArr(arr [4]string) {
arr[0] = "9999"
}
--- 地址传递:在test栈中会直接指向arr数组的数据。
// 所以可以改变数组中的元素
func main() {
arr := [...]string{"11", "22", "33", "444"}
testArr(&arr)
fmt.Println(arr) // [9999 22 33 444]
}
func testArr(arr *[4]string) {
arr[0] = "9999"
}
1.4 数组的应用案例
遍历数组从A加到Z,然后遍历输出:
go
func main() {
var arr [26]byte
for i := 0; i < 26; i++ {
arr[i] = 'A' + byte(i)
}
fmt.Println(arr)
// [65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90]
for _, v := range arr {
fmt.Printf("%c ", v)
}
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
}
二、切片
个数不确定时,可以使用切片。
2.1 切片的介绍
- 切片的英文是 slice
- 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制
- 切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度 len(slice)都一样
- 切片的长度是可以变化的,因此切片是一个可以动态变化数组。
- 切片定义的基本语法
var 切片名[类型]
比如: var a I int
2.2 切片的原理
切片是有三部分组成:
- 指向数组的地址
- 指向数组的长度
- 切片的容量长度
2.3 切片的三种使用
方式一:创建好的数组,进行切片
go
func main() {
var arr [26]byte
for i := 0; i < 26; i++ {
arr[i] = 'A' + byte(i)
}
for _, v := range arr {
fmt.Printf("%c ", v)
}
fmt.Println()
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Myslice := arr[1:10]
fmt.Printf("遍历Myslice切片元素: %c \n", Myslice) //slice: [66 67 68 69 70 71 72 73 74]
fmt.Printf("切片的第一个元素:%p, 对应数组的地址是:%p", &Myslice[0], &arr[1])
// 切片的第一个元素:0xc0420580a1, 对应数组的地址是:0xc0420580a1
}
内置的make来创作切片: