数组 & slice & map
与java的比较:
- 切片(Slice&集合):
- 在Go语言中,slice是一种动态大小的数据结构,类似于动态数组。它可以通过索引访问元素,并且可以自动扩展以容纳更多的元素。在Java中,ArrayList是一个类似于slice的数据结构,它可以动态地添加和删除元素。
- 映射(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{}
使用方式:
- 映射的访问:
可以通过键来访问映射中的值,例如value := myMap[key]。如果键不在映射中,将返回该类型的零值。 - 映射的修改:
可以通过键来修改映射中的值,例如myMap[key] = newValue。如果键不存在,会将该键添加到映射中,并将其值设置为指定值。 - 映射的删除:
可以使用delete函数删除映射中的键及其对应的值,例如delete(myMap, key)。 - 映射的遍历:
可以使用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子元素