Go语言基本数据结构

2021/06/01

Tags: Go

摘要:Go语言基本数据结构


数组

strings := [3]string{"1", "2", "2"}
intArray := [8]int{1, 2, 3, 4, 5, 5, 5, 55}

定义两个数组,fmt.Println(len(strings)) 可以使用len()函数得到数组的长度,strings[1]可以获取指定数组下标的元素。

所以通过以下方式可以遍历数组:

for i := 0; i < len(strings); i++ {
    fmt.Println(strings[i])
}

下文提供了更加优雅的方式。

slice

Go数组的长度不可变,Go提供了一种内置类型切片:slice,与数组相比,切片的长度不是固定的,可以动态扩容、添加元素。

slice1 := make([]string, 2)
fmt.Println(slice1)

slice1[0] = "22"
slice1[1] = "222"
fmt.Println(slice1)

slice1 = append(slice1, "33", "44", "55")
fmt.Println(slice1)
fmt.Println(len(slice1))

// 裁剪,从index 2 到index 4
sliceSub := slice1[2:4]
fmt.Println(sliceSub)

// 裁剪,从index 2 到最后
sliceSub2 := slice1[2:]
fmt.Println(sliceSub2)

slice从头部删除

a = []int{1, 2, 3}
a = a[1:] // 删除开头1个元素
a = a[N:] // 删除开头N个元素

a = append(a[:0], a[1:]...) // 删除开头1个元素
a = append(a[:0], a[N:]...) // 删除开头N个元素

a = a[:copy(a, a[1:])] // 删除开头1个元素
a = a[:copy(a, a[N:])] // 删除开头N个元素

slice从中间删除

a = append(a[:i], a[i+1:]...) // 删除中间1个元素
a = append(a[:i], a[i+N:]...) // 删除中间N个元素
a = a[:i+copy(a[i:], a[i+1:])] // 删除中间1个元素
a = a[:i+copy(a[i:], a[i+N:])] // 删除中间N个元素

slice从尾部删除

a = a[:len(a)-1] // 删除尾部1个元素
a = a[:len(a)-N] // 删除尾部N个元素

slice 扩容

slice2 := make([]string, 1, 1)
// cap()函数, 计算slice长度可以达到多少
fmt.Println("cap(slice1) is :", cap(slice1))

slice2[0] = "0"

slice2 = append(slice2, "3")
fmt.Println("cap(slice2) is :", cap(slice2))

numbers := []int{0, 1, 2, 3, 4, 5}

numbers = append(numbers, 6)

fmt.Println(numbers)
fmt.Println(cap(numbers))

通过cap()函数可以获取slice的容量,容量是make()函数的第三个参数,超过设置的容量再往slice中添加元素就会使slice扩容。

手动实现扩容:

// 实现切片扩容
var capslice = make([]int, 10, 10)
for i := range capslice {
    capslice[i] = i
}
fmt.Println(capslice)
// 创建新的切片,并且容量是之前切片的2倍
var capslice1 = make([]int, len(capslice), cap(capslice)*2)
copy(capslice1, capslice)
fmt.Println(capslice1, "caplice cap is :", cap(capslice1))

map

map是go预制的一种字典数据结构。

// map[key-type]val-type
map1 := make(map[string]string)
map1["1"] = "11"

map2 := make(map[string]int)

map2["2"] = 2
map2["3"] = 3

fmt.Println("map1:", map1)
fmt.Println("map2", map2)

map结构也可以嵌套:

map3 := make(map[string]int)

map3["a"] = 1
map3["b"] = 33

delete(map3, "b")
fmt.Println(map3)
fmt.Println(len(map3))
    
m := map[string]map[string]int{}
m["aa"] = map3

fmt.Println(m)

map中有个比较有意思的特性,获取某个元素是否在map中存在。

// 有意思的特性,_, psr := 赋值结果为bool
_, psr := map3["a"]
fmt.Println(psr)

// 输出结果为: true

使用range遍历

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

// 遍历slice
for i := range nums {
    fmt.Println(nums[i])
}

// 遍历map
map1 := map[string]string{"aa": "11", "bb": "22"}
for s := range map1 {
    fmt.Println(map1[s])
}

// 优雅地遍历map
for k, v := range map1 {
    fmt.Println("k : ", k, " v : ", v)
}

// 遍历字符串,获取Unicode
for i, c := range "balabala" {
    fmt.Println(i, " -> ", c)
}