go语言学习更多类型结构体,数组,切片和映射

指针

Go拥有指针。指针保存了值的内存地址。
类型*T 指向T类型值的指针。
&操作符会生成一个指向其操作数的指针。
*操作符表示指针指向的底层值
与c不同,Go没有指针运算。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
i, j := 42, 2701

p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i

p = &j // point to j
*p = *p / 37 // divide j through the pointer
fmt.Println(j) // see the new value of j
}

结构体

一个结构体(struct)就是一个字段的集合。
结合体字段使用点号来访问。
结构体字段可以通过结构体指针来访问。
结构体文法通过直接列出字段的值来重新分配一个结构体。
使用 Name: 语法可以仅列出部分字段。(字段名的顺序无关。)
特殊的前缀 & 返回一个指向结构体的指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

type Vertex struct {
X, Y int
}

var (
v1 = Vertex{1,2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)

func main() {
fmt.Println(v1, p, v2, v3)
}
//返回:
{1 2} &{1 2} {1 0} {0 0}

数组

类型[n]T表示拥有n个T类型的值的数组

1
2
//会将变量 a 声明为拥有有 10 个整数的数组。
var a [10]int

数组的长度是其类型的一部分,因此数组不能改变大小。

切片

类型[]T表示一个类型为T的切片
1
2
3
4
5
var a = [4]int{
1,2,3,4
}
var s = a[0,2] // [1 2]
var b = a[1,3] // [2 3]
切片通过两个下标来界定,即一个上界和一个下界,二者以冒号分隔:
1
2
3
4
5
a[low : high]
//它会选择一个半开区间,包括第一个元素,但排除最后一个元素。
//low 默认为0
//high 默认为切片的长度
a[0:10] == a[:10] == a[0:] == a[:]
切片的长度就是它所包含的元素个数。

切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。

1
2
3
4
//获取切片长度
var s = []int //零值 == nil
len(s) // 0
cap(s) // 0
用make函数创建切片
1
2
3
//第二个参数为长度,第三个参数为容量
a := make([]int,5)
b := make([]int,0,10)
切片的切片

切片可包含任何类型,甚至包括其他的切片

向切片追加元素

func append( s []T,vs …T) [ ]T
append 的第一个参数 s 是一个元素类型为 T 的切片,其余类型为 T 的值将会追加到该切片的末尾。

append 的结果是一个包含原切片所有元素加上新添加元素的切片。

Range

for 循环的range形式 可遍历切片或映射
当使用 for 循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
可以将下标或值赋予 _ 来忽略它。

若你只需要索引,去掉 , value 的部分即可。

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"

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
//返回
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
//i = 切片 pow 的下标
for i := range pow{
}
// 忽略切片下标。只取值
for _, value := range pow{
}

映射

映射将键映射到值。
映射的零值为 nil 。nil 映射既没有键,也不能添加键。
映射的文法与结构体相似,不过必须有键名。
若顶级类型只是一个类型名,你可以在文法的元素中省略它。
示例:var m = map[string]int

1
2
3
4
5
6
7
8
9
10
//设置会插入值
m['test'] = 111
//获取值
test := m['test']
//删除元素
delete(m,'test')
//通过双赋值检测某个键是否存在:
elem ,ok := m['test']
m中存在 test, ok为ture,反之为false
m中存在test, elem为值,反之为 类型的零值

函数值

函数也是值。它们可以像其它值一样传递。
函数值可以用作函数的参数或返回值。

1
2
3
4
5
//函数作为参数
func test(fn func(float64, float64)float64)float64{
//返回
return fn(3,4)
}
函数的闭包

Go 函数可以是一个闭包。闭包是一个函数值,它引用了其函数体之外的变量。该函数可以访问并赋予其引用的变量的值,换句话说,该函数被“绑定”在了这些变量上。