go语言数组切片映射相关知识点总结归纳 | 青训营

101 阅读4分钟

数组 & slice & map

与java的比较:

  1. 切片(Slice&集合):
  • 在Go语言中,slice是一种动态大小的数据结构,类似于动态数组。它可以通过索引访问元素,并且可以自动扩展以容纳更多的元素。在Java中,ArrayList是一个类似于slice的数据结构,它可以动态地添加和删除元素。
  1. 映射(Map):
  • Go语言的映射是一个键值对集合,类似于哈希表或字典。映射是无序的,键必须是唯一的。
  • Java中的映射接口是java.util.Map,实现该接口的常见类有java.util.HashMap和java.util.TreeMap。它们也提供了键值对的存储,但Java的映射是有序的,且键必须是唯一的。

数组

数组的声明

//固定长度的数组
var myArray1 [10]int
myArray2 := [10]int{1,2,3,4}
myArray3 := [4]int{11,22,33,44}

注意:固定⻓度的数组在传参的时候, 是严格匹配数组类型的

func printArray(myArray [4]int) { //这点和java不同
	//值拷贝
}

slice切片

类似于动态数组, 切⽚的扩容机制,append的时候,如果⻓度增加后超过容量,则将容量增加2倍

切片可以通过使用make函数来创建,例如slice := make([]int, length, capacity),其中length是切片当前的长度,capacity是切片底层数组的容量。也可以通过类型转换将一个数组转换为切片,例如slice := []int(array)

切片与底层数组是分离的,切片操作不会修改底层数组。切片的长度是当前元素在底层数组中的索引,而容量则是底层数组从切片的起始索引到数组末尾的长度。

切片的定义:

var slice0 []type
//一个切片在未初始化之前默认为 nil,长度为 0

var slice1 []type = make([]type, len)

// slice1 := make([]type, len)

slice2 :=make([]int,len,cap)//cap指定容量
// len 是数组的长度并且也是切片的初始长度

切片的初始化:

//声明slice1是一个切片,并且初始化,默认值是1,2,3。 长度len是3
slice1 := []int{1, 2, 3}

//声明slice1是一个切片,但是并没有给slice分配空间
var slice1 []int
slice1 = make([]int, 3) //开辟3个空间 ,默认值是0

//声明slice1是一个切片,同时给slice分配空间,3个空间,初始化值是0
var slice1 []int = make([]int, 3)

//声明slice1是一个切片,同时给slice分配空间,3个空间,初始化值是0, 通过:=推导出slice是一个切片
slice1 := make([]int, 3)

切片相关函数

  • len() 函数:获取长度。
  • cap() 函数:测量切片最长可以达到多少。

切⽚的⻓度和容量不同,⻓度表示左指针⾄右指针之间的距离,容量表示左指针⾄底层数组末尾的距离。

  • append()函数:追加新元素。如果当前容量不足,底层数组会自动扩容。切片的容量可以多次扩容,每次扩容容量会翻倍。
  • copy()函数:拷贝切片。将原切片的内容复制到新的切片中,不会改变切片的长度和容量。
/* 添加多个元素 */
   numbers = append(numbers, 2,3,4)

/* 拷贝 numbers 的内容到 numbers1 */
   copy(numbers1,numbers)

切片的截取

func main() {
   /* 创建切片 */
   numbers := []int{0,1,2,3,4,5,6,7,8}   
   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)


}
/*
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
len=3 cap=7 slice=[2 3 4]
*/

可以通过delete函数删除切片中的元素,例如slice = append(slice[:index-1], slice[index+1:]...)。

切片可以使用==运算符进行比较,比较的是切片的长度、容量和底层数组的内容是否相同。

map

类似于java中的map<key,value>

声明方式:

映射可以通过make函数来创建,例如myMap := make(map[keyType]valueType),其中keyType是键的类型,valueType是值的类型。也可以通过直接赋值来创建一个空的映射,例如myMap := map[keyType]valueType{}

使用方式:

  1. 映射的访问:
    可以通过键来访问映射中的值,例如value := myMap[key]。如果键不在映射中,将返回该类型的零值。
  2. 映射的修改:
    可以通过键来修改映射中的值,例如myMap[key] = newValue。如果键不存在,会将该键添加到映射中,并将其值设置为指定值。
  3. 映射的删除:
    可以使用delete函数删除映射中的键及其对应的值,例如delete(myMap, key)
  4. 映射的遍历:
    可以使用range关键字遍历映射的键值对,例如for key, value := range myMap { ... }
//增删改查
val, key := language["php"]  //查找是否有php这个子元素
if key {
    fmt.Printf("%v", val)
} else {
    fmt.Printf("no");
}

language["php"]["id"] = "3" //修改了php子元素的id值
language["php"]["nickname"] = "hello" //增加php元素里的nickname值
delete(language, "php")  //删除了php子元素