A Tour Of Go - 复杂数据类型

指针

指针(*T)指向值(T)的内存地址, 零值为 nil, &T 用于获取值(T)对应的地址

定义指针类型
var p *int

给指针赋值(变量的地址)
v := 1
p = &v

改变变量值可以使用变量本身, 也可以使用指针地址
v = 2
*p = 3

结构体

type Animal struct {
mType int
mName string
}

monkey := Animal{1, “猴子”}

monkey.mName = “金丝猴”
fmt.Print(monkey.mName)

p := &monkey
p := &Animal{1, “猴子”}

// (*p).mType 简写成 p.mType
p.mType = 2
fmt.Print(p.mType)

初始化时不指定 key 名, 那么就要保持内容顺序, 否则使用 Animal{mName: “猴子”, mType: 2}
初始化空对象 Animal{}, 初始化部分对象 Animal{mName: “猴子”}

数组

var arr1 [3]int
arr2 := [3]int{1,2,3}

Slice

数组的引用, 改动将引发数组修改, 其他切片也对应修改

var slc []int = arr1[include:exclude] 其中 include 为下界默认0, exclude 为上界默认数组长度, 均可省(但是:不能省)

var slc []int = []int{1,2,3} 先声明数组[3]int{1,2,3} 然后赋值给 slc

len(slc) 当前切片元素个数, cap(slc) 当前切片可容纳元素个数 - 切片在数组的起始位置到底层数组长度

数组可以切片, 切片也可以切片

nil 切片, 定义了但是未与底层数组关联, len 和 cap 都是 0

1
2
var s []int
if s == nil { // nil slice }

slice 可以是任何类型, [][]string 表示二维数组

使用 make, append

v := make([]int, len, cap)

append(v, 1, …)

数组循环

可以使用 _ 替代不需要的 id, 如果给一个值表示 id

1
2
3
4
5
6
7
for id,val := range []int{1,2,3} {
fmt.Printf("%d => %d\n", id, val)
}

for _, val := ...

for id := ...

练习

1
2
3
4
5
6
7
8
9
10
11
12
func Pic(dx, dy int) [][]uint8 {
p := make([][]uint8, dy)

for id, v := range p {
for i := 0; i < dx; i++ {
v = append(v, uint8(i*id))
}
p[id] = v
}

return p
}

map

零值为 nil, 没有 key, 也不能添加 key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var m map[string]string

m = make(map[string][string])
m["k"] = "val"
fmt.Print(m["k"])
delete(m, "k")

elem, ok := m["k"]
if (!ok) { // k not exist in m, elem is zero value of type => 0, "", false, nil... }

var m = map[string][string]{
"k1": "v1",
"k2": "v2"
...
}

练习

1
2
3
4
5
6
7
8
func WordCount(s string) map[string]int {
a := strings.Fields(s)
counter := make(map[string]int)
for _, val := range a {
counter[val] += 1
}
return counter
}

函数参数

1
2
3
4
5
6
7
8
9
10
func compute(x int, y int, f func(int, int) int) int {
return f(x, y)
}

add := func(a, b int) int {
return a + b
}

add(1, 2)
compute(1, 2, add)

闭包

在函数体中的变量引用函数体外的值

func counter() func(int) int {
counts := 0
return func(x int) int {
counts += x
return counts
}
}

这里返回的函数就是闭包, 引用了函数体外面的变量 counts.

note: 当多次调用 counter 方法后, 返回的多个闭包引用的 counts 不同.

练习

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
func fibonacci() func() int {
fib := make(map[int]int)

fib[0] = 0
fib[1] = 1

times := -1

return func() int {
times += 1
if times < 2 {
return fib[times]
}
fib[times] = fib[times-1] + fib[times-2]

return fib[times]
}
}

func main() {
f := fibonacci()
for i := 0; i < 20; i++ {
fmt.Println(f())
}
}
Donate - Support to make this site better.
捐助 - 支持我让我做得更好.