目录
一、数组1. 定义数组:四种方式
package main
import "fmt"
func main() {
// 数组定义 第一种方式
var arr1 [3]int
var strArr [2]string
arr1[0] = 1
arr1[1] = 213
arr1[2] = 2
strArr[0] = "php"
strArr[1] = "golang"
fmt.Println(arr1) // [1 213 2]
fmt.Println(strArr) // [php golang]
// 第二种方式
var arr2 = [3]int{1, 22, 32}
fmt.Println(arr2) // [1 22 32]
// 第三种方式 不再输入数组数量,让程序自动判断
var arr3 = [...]int{21, 21, 321, 432, 32}
fmt.Printf("数组为:%v 长度为:%v\n", arr3, len(arr3)) // 数组为:[21 21 321 432 32] 长度为:5
// 第四种方式 指定索引值
var arr4 = [...]int{0: 12, 1: 1, 3: 234}
fmt.Printf("数组为:%v 长度为:%v\n", arr4, len(arr4)) // 数组为:[12 1 0 234] 长度为:4,也就是3-1
}
2. 遍历数组
package main
import "fmt"
func main() {
// 遍历数组
arr5 := [...]int{12, 321, 1421, 321, 432}
for i := 0; i < len(arr5); i++ {
fmt.Println(arr5[i]) // 12, 321, 1421, 321, 432
}
for k, v := range arr5 {
fmt.Printf("k= %v v=%v\n", k, v) // k= 0 v=12 k= 1 v=321 k= 2 v=1421 k= 3 v=321 k= 4 v=432
}
}
3. 练习题
package main
import "fmt"
func main() {
// 练习 1 求数组的和 1,3,5,1 及平均值
arr6 := [...]int{1, 2, 5, 22}
sum := 0
for i := 0; i < len(arr6); i++ {
sum += arr6[i]
}
fmt.Printf("和:%v 平均值为:%.2f\n", sum, float64(sum)/float64(len(arr6))) // 和:30 平均值为:7.50 %.2f表示保留两位小数
// 练习2 求最大值并拿到key
arr7 := [...]int{15, 1, 33, 85, 12, 32}
max := arr7[1]
index := 0
for i := 0; i < len(arr7); i++ {
if arr7[i] > max {
max = arr7[i]
index = i
}
}
fmt.Printf("最大值:%v 下标:%v\n", max, index) // 最大值:85 下标:3
// 练习3 求 数组中相加等于8的key,并且以(1, 3)形式展现
arr8 := [...]int{1, 3, 5, 7, 8, 1}
for i := 0; i < len(arr8); i++ {
for j := i + 1; j < len(arr8); j++ {
if arr8[i]+arr8[j] == 8 {
fmt.Printf("(%v, %v)\n", i, j) // (0, 3) (1, 2) (3, 5)
}
}
}
}
二、多维数组
1. 两种定义方式
package main
import "fmt"
func main() {
// 定义多维数组 两种方式:第一种
var arr1 = [3][2]string{
{"北京", "上海"},
{"济南", "重庆"},
{"聊城", "德州"},
}
fmt.Println(arr1)
// 第二种方式 首位可以用...代替,之后的不可以
var arr2 = [...][2]string{
{"北京", "上海"},
{"济南", "重庆"},
{"聊城", "德州"},
}
fmt.Println(arr2)
}
2. 遍历多维数组
package main
import "fmt"
func main() {
// 定义多维数组 两种方式:第一种
var arr1 = [3][2]string{
{"北京", "上海"},
{"济南", "重庆"},
{"聊城", "德州"},
}
fmt.Println(arr1)
// 第二种方式 首位可以用...代替,之后的不可以
var arr2 = [...][2]string{
{"北京", "上海"},
{"济南", "重庆"},
{"聊城", "德州"},
}
fmt.Println(arr2)
// 遍历二维数组
for k1, _ := range arr1 {
for _, v2 := range arr1[k1] {
fmt.Print(v2) // 北京上海济南重庆聊城德州
}
}
for i := 0; i < len(arr2); i++ {
for j := 0; j < len(arr2[i]); j++ {
fmt.Print(arr2[i][j]) // 北京上海济南重庆聊城德州
}
}
}
3. 数组与切片的不同
1) 数组中是操作两个内存,所以两个数组相等后,改变其中的一个另外一个不会改变
2) 切片是操作同一个内存,这种类型称之为引用类型,那么更改其中一个切片之后,另外一个也会跟着改变
package main
import "fmt"
func main() {
// 数组与切片的不同点
var arr3 = [3]int{1, 2, 3}
arr4 := arr3
arr3[0] = 3
// 数组中是操作两个内存,所以两个数组相等后,改变其中的一个另外一个不会改变
fmt.Println(arr3) // [3 2 3]
fmt.Println(arr4) // [1 2 3]
var sec1 = []int{1, 2, 3}
sec2 := sec1
sec1[0] = 3
// 切片是操作同一个内存,这种类型称之为引用类型,那么更改其中一个切片之后,另外一个也会跟着改变
fmt.Println(sec1) // [3 2 3]
fmt.Println(sec2) // [3 2 3]
}
三、切片
1. 定义切片:4种方式
package main
import "fmt"
func main() {
// 定义切片 第一种方式
var a []int
fmt.Printf("值:%v 类型:%T\n", a, a) // 值:[] 类型:[]int
// 第二种方式
var b = []int{1, 2, 3}
fmt.Printf("值:%v 类型:%T\n", b, b) // 值:[1 2 3] 类型:[]int
// 第三种方式,基于数组声明切片
var c = [4]string{"php", "java", "nodejs", "golang"}
d := c[:] // [:]获取数组中所有的值
fmt.Printf("值:%v 类型:%T\n", d, d) // 值:[php java nodejs golang] 类型:[]string
e := c[1:3] // 获取key从1开始到3结束,但又不包含3的值
fmt.Println(e) // [java nodejs]
f := c[1:] // 获取key从1开始到末位的值
fmt.Println(f) // [java nodejs golang]
g := c[:3] // 获取key从3到开始的值,但又不包含3的值
fmt.Println(g) // [php java nodejs]
// 第四种方式,基于切片声明切片.跟第三种方式类似,不再一一展示。
var h = []int{1, 2, 3, 4}
i := h[:]
fmt.Println(i) //[1 2 3 4]
// 空的切片默认值为 nil
var j []string
fmt.Println(j == nil) // true
}
2. 遍历切片
package main
import "fmt"
func main() {
// 遍历切片,跟遍历数组一样
var arr1 = []int{1, 2, 3, 5, 55}
for i := 0; i < len(arr1); i++ {
fmt.Print(arr1[i], "\n") // 1 2 3 5 55
}
for k, v := range arr1 {
fmt.Printf("k=%v v=%v\n", k, v) // k=0 v=1 k=1 v=2 k=2 v=3 k=3 v=5 k=4 v=55
}
}
3. 切片的长度容量解释
1)长度:获取切片/数组中所有值的数量
2)容量:获取切片中从第一个元素到原始切片最后一个元素的数量
package main
import "fmt"
func main() {
// 长度:获取切片中所有值的数量
// 容量:获取切片中从第一个元素到原始切片/数组最后一个元素的数量
var slice2 = []int{1, 2, 3, 4, 5, 6}
slice3 := slice2[1:4] // 2,3,4
fmt.Printf("长度:%d 容量:%d\n", len(slice3), cap(slice3)) // 长度:3 容量:5 从key为1的开始数,一直到原切片最后一个
slice4 := slice2[2:]
fmt.Printf("长度:%d 容量:%d\n", len(slice4), cap(slice4)) // 长度:4 容量:4 从key为2的开始数,一直到原切片最后一个
slice5 := slice2[:3]
fmt.Printf("长度:%d 容量:%d\n", len(slice5), cap(slice5)) // 长度:3 容量:6 从key为0的开始数,一直到原切片最后一个
}
结合图片来更进一步,初次接触 “ 指针 ”
4. 使用make()函数创建切片
package main
import "fmt"
func main() {
// 使用make()函数构建切片 make(类型、长度、容量)
slice1 := make([]int, 4, 4)
fmt.Printf("值:%v 长度:%d 容量:%d\n", slice1, len(slice1), cap(slice1)) // 值:[0 0 0 0] 长度:4 容量:4
slice1[0] = 1
fmt.Printf("值:%v 长度:%d 容量:%d\n", slice1, len(slice1), cap(slice1)) //值:[1 0 0 0] 长度:4 容量:4
}
5. 直接相等的切片与copy()切片的区别
package main
import "fmt"
func main() {
// 切片是引用数据类型,如果直接相等,那么改变其中一个的值另外一个也会跟着改变
slice2 := make([]int, 2, 3)
slice2[0] = 1
slice2[1] = 112
slice3 := slice2
fmt.Println(slice2) // [1 112]
fmt.Println(slice3) // [1 112]
slice3[0] = 123
fmt.Println(slice2) // [123 112]
fmt.Println(slice3) // [123 112]
// 使用copy函数可以做到改变其中一个的值,另外一个不跟着改变
slice4 := []int{1, 2, 3, 4}
slice5 := make([]int, 4, 4)
copy(slice5, slice4)
fmt.Println(slice4) // [1 2 3 4]
fmt.Println(slice5) // [1 2 3 4]
slice5[2] = 89
fmt.Println(slice4) // [1 2 3 4]
fmt.Println(slice5) // [1 2 89 4]
}
6. 切片追加、合并、删除元素
package main
import "fmt"
func main() {
// 向切片中添加数据
slice6 := []int{1, 2}
//slice6[2] = 2 // 添加数据必须要用 append函数,这种是错误的
slice6 = append(slice6, 123)
fmt.Println(slice6) // [1 2 123]
// 追加多个元素
slice6 = append(slice6, 123, 123, 321)
fmt.Println(slice6) // [1 2 123 123 123 321]
// 两个切片合并
slice7 := []int{1, 2}
slice8 := []int{2, 3}
slice9 := append(slice7, slice8...) // 注意,切片合并,后面的切片要加上 ...
fmt.Println(slice9) // [1 2 2 3]
// 删除元素
slice10 := []int{1, 2, 3, 4, 5}
slice10 = append(slice10[:1], slice10[2:]...) // 删除key为1的值
fmt.Println(slice10) // [1 3 4 5]
}