Hello GoLand: https://blog.yexca.net/archives/154
GoLand (var and const) 变量与常量: https://blog.yexca.net/archives/155
GoLand (func) 函数: https://blog.yexca.net/archives/156
GoLand (slice and map) 切片: This Page
GoLand (OOP) 面向对象: https://blog.yexca.net/archives/162
GoLand (reflect) 反射: https://blog.yexca.net/archives/203
Go 的切片是对数组的抽象
数组
数组的长度不可改变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
import "fmt"
func main() {
// 定义方式一
var arr1 [10]int
// 遍历
for i := 0; i < len(arr1); i++ {
fmt.Println("arr1[", i, "]:", arr1[i])
}
// 定义方式二,赋值
arr2 := [10]int{0, 1, 2, 3}
// range遍历
for index, value := range arr2 {
fmt.Println("index =", index, "value =", value)
}
// 定义不同长度
var arr3 [4]int
fmt.Printf("type of arr1 is %T\n", arr1) // [10]int
fmt.Printf("type of arr1 is %T\n", arr2) // [10]int
fmt.Printf("type of arr1 is %T", arr3) // [4]int
}
编译运行后可以发现 arr3 与 arr1,arr2 类型不同,那么在定义函数形参时也需要指定相应类型
1
2
3
4
5
func test(arr [4]int) {
for i := 0; i < len(arr); i++ {
fmt.Println("fmt_arr[", i, "]:", arr[i])
}
}
上述函数只能传递 arr3,值传递,修改值不影响原数据
定义切片
与数组相比切片长度不固定,可追加元素 (动态数组),在追加时可能使切片的容量增大
定义切片可以通过声明一个未指定大小的数组
1
2
3
var name []type
// 例如
var s []int
或者使用 make() 函数来创建切片
1
2
3
var slice []type = make([]type, len) // len 为切片初始长度
// 也可以简写为
slice := make([]type, len)
可以使用可选参数 capacity 指定容量,省略与 length 相同
1
var slice []type = make([]type, length, capacity)
切片初始化
直接初始化
1
s := []int {1, 2, 3}
将数组值为切片初始化,从 startIndex 到 endIndex-1,这俩值都可省略
1
s := arr[startIndex:endIndex]
省略 startIndex 或 endIndex 表示从第一个元素开始索引或索引到最后一个元素
len() and cap()
切片是可以索引的,通过 len() 函数获取长度
而 cap() 为计算容量的方法,可以测量切片最长可以达到多少
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
import "fmt"
// 切片传递为引用传递,函数内修改影响原数据
func printSlice(slice []int) {
fmt.Printf("len=%d, cap=%d, slice=%v", len(slice), cap(slice), slice)
}
func main() {
s := make([]int, 3, 5)
printSlice(s)
}
/*
* 输出
* len=3, cap=5, slice=[0 0 0]
*/
空切片
一个切片在未初始化之前默认为 nil (空切片),长度为 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import "fmt"
func printSlice(slice []int) {
fmt.Printf("len=%d, cap=%d, slice=%v\n", len(slice), cap(slice), slice)
}
func main() {
var s []int
printSlice(s)
// 判断是否为空
if s == nil {
fmt.Println("slice is empty")
}
}
切片截取
通过设置上下限截取切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main
import "fmt"
func printSlice(slice []int) {
fmt.Printf("len=%d, cap=%d, slice=%v\n", len(slice), cap(slice), slice)
}
func main() {
s := []int{0, 1, 2, 3, 4, 5, 6, 7}
// 打印原始切片
fmt.Println(s)
// 从2(包含)到5(不包含)
printSlice(s[2:5])
// 从第一个到5(不包含)
printSlice(s[:5])
// 从第二个到最后一个
printSlice(s[2:])
// 这样赋值修改 subS 将影响到 s
subS := s[1:6]
printSlice(subS)
}
append() and copy()
增加切片的容量与拷贝切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main
import "fmt"
func printSlice(slice []int) {
fmt.Printf("len=%d, cap=%d, slice=%v\n", len(slice), cap(slice), slice)
}
func main() {
var s []int
printSlice(s)
// 增加一个元素
s = append(s, 0)
printSlice(s)
// 增加多个元素
s = append(s, 1, 2, 3, 4)
printSlice(s)
// 创建一个容量为 s 两倍的 s2
s2 := make([]int, len(s), cap(s)*2)
// 拷贝 s 到 s2,此时修改 s2 不影响 s
copy(s2, s)
printSlice(s2)
}
切片的扩容:如果追加值超过容量,则将容量增加两倍
map
map 有两种声明方式
1
2
3
4
5
6
7
8
9
10
11
package main
import "fmt"
func main() {
var map1 = make(map[string]string)
// 插入数据
map1["one"] = "1"
map1["two"] = "2"
fmt.Println(map1) // map[one:1 two:2]
}
第二种
1
2
3
4
5
6
7
8
9
10
11
package main
import "fmt"
func main() {
map1 := map[string]string{
"one": "1",
"two": "2",
}
fmt.Println(map1)
}
map 嵌套
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import "fmt"
func main() {
map1 := make(map[string]map[string]string)
map1["first"] = make(map[string]string, 2)
map1["first"]["one"] = "1"
map1["first"]["two"] = "2"
fmt.Println(map1)
}
/*
* 输出
* map[first:map[one:1 two:2]]
*/
修改遍历与删除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main
import "fmt"
func main() {
map1 := make(map[string]map[string]string)
map1["first"] = make(map[string]string, 2)
map1["first"]["one"] = "1"
map1["first"]["two"] = "2"
// 修改
map1["first"]["one"] = "one"
fmt.Println(map1)
//遍历
for key, value := range map1{
fmt.println("key =", key, "value =", value)
}
// 删除
delete(map1, "first")
fmt.Println(map1)
}
判断是否有某值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import "fmt"
func main() {
map1 := make(map[string]string)
map1["one"] = "1"
val, key := map1["one"]
if key {
fmt.Println(val)
} else {
fmt.Println("empty")
}
}