Go-数组,切片,map

2022-10-3 diaba 基础

一、Array(数组)

数组是具有相同数据类型的元素组成的一组长度固定的序列,数组的长度不可变化,数组元素是可修改的。

1.1、声明

数组声明需要指定组成元素的类型以及元素的个数(长度),长度是数组类型的一部分,数组被声明后,数组长度不可修改,数组元素会根据对应类型的零值进行初始化。

var name [4]string var age [3]int fmt.Println(name) // [   ] fmt.Println(name) // [0 0 0] 

1.2、字面量

在声明时初始化值

var name [3]string = [3]string{"alex", "eric", "kk"}
fmt.Println(name) //[alex eric kk] 

使用初始化元素数量推导数组长度

name := [...]string{"alex", "eric", "kk"}
fmt.Println(len(name)) //3 

指定位置初始化

name := [10]string{0: "alex", 3: "eric", 6: "kk"}
fmt.Println(name) //[alex   eric   kk   ] 

1.3、关系运算符

关系运算符==!=,只能比较长度与类型一致的数组

a1 := [2]int{11, 22}
a2 := [2]int{22, 33} 

fmt.Println(a1 == a2) //false fmt.Println(a1 != a2) //true

1.4、获取数组长度

获取数组长度可以使用len函数

name := [...]string{"alex", "eric", "kk"}
fmt.Println(len(name)) //3 

1.5、访问与修改

数组的访问与修改使用索引,索引从0开始,到数组长度-1为止

name := [10]string{0: "alex", 3: "eric", 6: "kk"}
fmt.Println(name[0],name[len(name)-1]) //alex  name[0] = "new" name[len(name)-1] = "alex" fmt.Println(name[0], name[len(name)-1]) //new alex 

1.6、切片

获取数组的一部分作为切片

array[start:end]/array[start:end:cap](end<=cap<=len)

a1 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
a2 := a1[1:6]
fmt.Printf("%T, %v\n", a2, a2) //[]int, [2 3 4 5 6] a3 := a1[1:3:3]
fmt.Printf("%T, %v\n", a3, a3) //[]int, [2 3] 

1.7、遍历

遍历数组可以使用for+len函数和for range两种方法

a1 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i := 0; i < len(a1); i++ {
	fmt.Printf("%d : %v\n", i, a1[i])
} for i, v := range a1 {
	fmt.Printf("%d : %v\n", i, v)
} 

二、多维数组

多维数组就是数组中的元素也是数组

2.1、声明与初始化

多维数组的声明与初始化与数组基本一致,使用初始化元素数量推导数组长度只有第一维数组可使用

a1 := [...][3]int{{1, 2, 3}, {2, 3, 4}}
fmt.Println(len(a1)) 

2.2、访问与修改

a1 := [...][3]int{{1, 2, 3}, {2, 3, 4}}
fmt.Println(a1[1][1]) //3 a1[1][1] = 33 fmt.Println(a1[1][1]) //33 

2.3、遍历

for i := 0; i < len(a1); i++ { for j := 0; j < len(a1[i]); j++ {
		fmt.Printf("[%d %d]: %v\n", i, j, a1[i][j])
	}
} for i, line := range a1 { for j, v := range line {
		fmt.Printf("[%d %d]: %v\n", i, j, v)
	}
} 

三、Slice(切片)

切片(Slice)是一个拥有相同类型元素的可变长度的序列,是长度可变的数组,切片由三部分组成

指针:指向切片第一个元素指向的数组元素的地址

长度:切片元素的数量

容量:切片开始第一个元素到结束位置元素(底层数组元素末尾)的数量

3.1、声明

切片声明需要指定组成元素的类型,但不需要指定存储元素的数量(长度)。在切片声明后,会被初始化为nil,表示暂不存在的切片

var names []string var ages []int 

3.2、初始化

使用字面量初始化

var names []string{"alex","eric","kk"} 

使用字面量初始化空切片

stu1 := []string{} 

指定长度和容量字面量初始化

stu2 := []string{0: "alex", 4: "eric"} 

使用make函数初始化

stu3 := make([]string, 3) //通过make函数创建长度为3的切片 stu4 := make([]string, 2, 5) //通过make函数创建长度为2,容量为5的切片,长度必须小于等于容量 

使用数组切片操作初始化

stu := [5]string{"zhangsan", "lisi", "wangwu", "zhaoliu", "peiqi"}
stu5 := stu[1:3] //array[start:end] stu6 := stu[1:2:3] //array[start:end:cap](end<=cap<=len) 

3.3、操作

获取切片长度和容量

num := make([]int, 4, 5)
fmt.Println(len(num), cap(num)) 

通过对编号对切片元素进行访问和修改,元素的编号从左到右依次为:0, 1, 2, …, n(n为切片长度-1)

num = []int{1, 2, 3, 4}
num[0] = 11 fmt.Println(num[0], num[len(num)-1]) 

切片创建新的切片,切片结束位置小于原切片容量,新创建切片长度和容量计算:len: end-start, cap: src_cap-start,

num1 := num[:] 
num2 := num[0:2:3] //slice[start:end:cap]可用于限制新切片的容量值, end<=cap<= src_cap fmt.Println(num1, num2) //[11 2 3 4] [11 2] 

切片共享底层数组,若某个切片元素发生变化,则数组和其他有共享元素的切片也会发生变化

num[0] = 111 fmt.Println(num1, num2) //[111 2 3 4] [111 2] 

遍历,同数组一致

a1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} for i := 0; i < len(a1); i++ {
	fmt.Printf("%d : %v\n", i, a1[i])
} for i, v := range a1 {
	fmt.Printf("%d : %v\n", i, v)
} 

切片复制:复制元素数量为 src元素数量和 dest元素数量的最小值

a1 := []int{1, 2, 3}
a2 := []int{10, 20, 30, 40, 50, 60}
a3 := []int{100, 200, 300, 400, 500, 600, 700, 800, 900} copy(a1, a2)
fmt.Println(a1, a2) //[10 20 30] [10 20 30 40 50 60] copy(a3, a2)
fmt.Println(a3, a2) //[10 20 30 40 50 60 700 800 900] [10 20 30 40 50 60] 

3.4、使用

新增元素

使用 append对切片增加一个或多个元素并返回修改后切片,当长度在容量范围内时只增加长度,容量和底层数组不变。当长度超过容量范围则会创建一个新的底层数组并对容量进行智能运算(元素数量<1024时,约按原容量 1倍增加,>1024时约按原容量 0.25倍增加)

 a1 := []int{1, 2, 3}
a1 = append(a1, 4, 5)
fmt.Printf("%d,%d,%v\n", len(a1), cap(a1), a1) //5,6,[1 2 3 4 5] a2 := a1[:]
a2 = append(a2, 6, 7, 8, 9)
fmt.Printf("%d,%d,%v\n", len(a2), cap(a2), a2) //9,12,[1 2 3 4 5 6 7 8 9] 

移除元素

a1 := []int{1, 2, 3, 4, 5, 6} copy(a1[3:], a1[4:])
fmt.Println(a1) //[1 2 3 5 6 6] fmt.Println(a1[:len(a1)-1]) //[1 2 3 5 6] 

3.5、队列

先进先出

queue := []int{1, 2, 3}
fmt.Println(queue[0])
queue = queue[1:]
fmt.Println(queue[0])
queue = queue[1:]
fmt.Println(queue[0]) 

3.6、堆栈

先进后出

stack := []int{1, 2, 3}
fmt.Println(stack[len(stack)-1])
stack = stack[:len(stack)-1]
fmt.Println(stack[len(stack)-1])
stack = stack[:len(stack)-1]
fmt.Println(stack[len(stack)-1]) 

四、多维切片

切片的元素也是切片,就是多维切片

4.1、声明和初始化

num := [][]int{{1, 2, 3}, {4, 5, 6}} 

4.2、修改

num[0][1] = 22 fmt.Println(num) //[[1 22 3] [4 5 6]] 

4.3、切片

num1 := num[0:1]
fmt.Println(num1) 

4.4、遍历

for i := 0; i < len(num); i++ { for j := 0; j < len(num[i]); j++ {
		fmt.Printf("[%d %d]: %v\n", i, j, num[i][j])
	}
} for i, line := range num { for j, v := range line {
		fmt.Printf("[%d %d]: %v\n", i, j, v)
	}
} 

4.5、新增元素

num = append(num, []int{7, 8, 9})
num[0] = append(num[0], 10)
fmt.Println(num) //[[1 2 3 10] [4 5 6] [7 8 9]] 

4.6、切片复制

num := [][]int{{1, 2, 3}, {4, 5, 6}}
num1 := [][]int{{}, {}} copy(num1, num)
fmt.Println(num1) //[[1 2 3] [4 5 6]] 

五、map(映射)

映射是存储一系列无序的 key/value对,通过 key来对 value进行操作(增、删、改、查)。

映射的 key只能为可使用==运算符的值类型(字符串、数字、布尔、数组),value可以为任意类型。

5.1、声明

map声明需要指定组成元素key和value的类型,在声明后,会被初始化为nil,表示暂不存在的映射

var metrics map[string]int var coordinate map[[2]float64]string 

5.2、初始化

使用字面量初始化

metrics := map[string]int{"up_time": 20}
coordinate := map[[2]float64]string{{11022.11, 122321.00}: "shanghai"}
fmt.Println(metrics, coordinate) 

使用字面量初始化空映射

scores := map[string]int{}
fmt.Println(scores) 

使用make函数初始化

points := make(map[string]int)
fmt.Println(points) 

5.3、操作

获取元素数量

metrics := map[string]int{"up_time": 20}
coordinate := map[[2]float64]string{{11022.11, 122321.00}: "shanghai"}
fmt.Println(len(metrics), len(coordinate)) 

访问

//当访问key存在与映射时则返回对应的值,否则返回值类型的零值 fmt.Println(metrics["up_time"]) //20 fmt.Println(metrics["systemd_unit_state"]) //0 

判断key是否存在

//通过key访问元素时可接收两个值,第一个值为value,第二个值为bool类型表示元素是否存在,若存在为true,否则为false ret, ok := metrics["up_time"]
fmt.Println(ret, ok) // 20 true 

修改与增加

使用 key对映射赋值时当 key存在则修改 key对应的 value,若 key不存在则增加 key和value

metrics["up_time"] = 30 metrics["systemd_unit_state"] = 1 fmt.Println(metrics) //map[systemd_unit_state:1 up_time:30] 

删除

delete(metrics, "systemd_unit_state")
fmt.Println(metrics) //map[up_time:30] 

遍历

for k, v := range metrics {
	fmt.Printf("%v,%v\n", k, v)
}

标签: go基础

发表评论:

Powered by emlog 京ICP备15045175号-1 Copyright © 2022