基本语法
变量初始化
1
2
3
var s string = "string"
var s = "string"
s := "string"
二维切片初始化
1
2
3
4
slice1 := make([][]bool, m)
for i := range slice1 {
slice1[i] = make([]bool, n)
}
变量自增
只有后缀自增或自减,并且必须单独一行(除了在range语句中)。
条件判断语句中的初始变量可以在布尔表达式里,并且不能使用0/1作为判断条件。
1
2
3
if cond := true; cond {
fmt.Println()
}
随机数
生成 [0, 99] 的随机数
1
2
3
rand.Seed(time.Now().UnixNano())
r := rand.Intn(100)
fmt.Println(r)
栈/队列
Go 语言中的栈和队列都是基于切片实现的。
1
2
3
4
5
6
7
8
9
10
11
stack := make([]int, 0) //创建切片
stack = append(stack, 10) //push压入栈
value := stack[len(stack)-1] // 取栈顶的值
stack = stack[:len(stack)-1] //pop弹出
len(stack) == 0 //检查栈空
queue := make([]int, 0) //创建切片
queue = append(queue, 10) //enqueue入队
v := queue[0] // 取队首的值
queue = queue[1:] //dequeue出队
len(queue) == 0 //检查队列为空
合并切片
1
2
3
4
slice1 := []string{"Moe", "Larry", "Curly"}
slice2 := []string{"php", "golang", "java"}
slice3 = append(slice1, slice2...)
fmt.Println(slice3)//[Moe Larry Curly php golang java]
整数和字符串转换
1
2
3
4
5
6
7
8
9
10
11
// string to int, "99" -> 99
int, err := strconv.Atoi(str)
// asscii to string, 97 -> "a"
str := string(asscii) // asscii to string
// int to string, 10 -> "10"
str := fmt.Sprintf("%d", int)
str := strconv.Itoa(int)
str := strconv.FormatInt(int, 10)
Range 用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 数组
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
// Map
for key, value := range oldMap {
newMap[key] = value
}
for key := range oldMap {
fmt.Println(oldMap[key])
}
for _, value := range oldMap {
fmt.Println(value)
}
// 字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, c := range "go" {
fmt.Println(i, c, string(c)) //0 103 g \n 1 111 o
}
最值
1
2
3
4
5
6
7
8
9
10
11
fmt.Printf("int min - max: %d - %d\n", math.MinInt, math.MaxInt) // int
fmt.Printf("int8 min - max: %d - %d\n", math.MinInt8, math.MaxInt8) // int8
fmt.Printf("int16 min - max: %d - %d\n", math.MinInt16, math.MaxInt16) // int16
fmt.Printf("int32 min - max: %d - %d\n", math.MinInt32, math.MaxInt32) // int32
fmt.Printf("int64 min - max: %d - %d\n", math.MinInt64, math.MaxInt64) // int64
// unsigned
fmt.Printf("uint min - max: %d - %d\n", uint(0), uint(math.MaxUint)) // uint
fmt.Printf("uint8 min - max: %d - %d\n", 0, math.MaxUint8) // uint8
fmt.Printf("uint16 min - max: %d - %d\n", 0, math.MaxUint16) // uint16
fmt.Printf("uint32 min - max: %d - %d\n", 0, math.MaxUint32) // uint32
fmt.Printf("uint64 min - max: %d - %d\n", 0, uint64(math.MaxUint64)) // uint64
排序
1
2
3
4
5
6
7
8
9
10
11
12
// int
array := []int{3, 1, 34, 25, 14, 5}
sort.Ints(array) // 升序
fmt.Println(array)
sort.Sort(sort.Reverse(sort.IntSlice(array))) // 降序
fmt.Println(array)
// string
array1 := []string{"ss", "sa", "avs", "vs"}
sort.Strings(array1)
fmt.Println(array1)
sort.Sort(sort.Reverse(sort.StringSlice(array1)))
fmt.Println(array1)
自定义排序
1
2
3
4
5
6
7
8
array := []int{3, 17, 1, 34, 25, 14, 5}
sort.Slice(array, func(i, j int) bool {
if abs(array[i]-9) != abs(array[j]-9) {
return abs(array[i]-9) < abs(array[j]-9)
}
return array[i] < array[j]
})
fmt.Printf("%+v", array)
Map 用法
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
m := make(map[string]int) // 初始化
m := map[string]int{ // 使用组合字面量初始化
"apple": 1,
"banana": 2,
"orange": 3,
}
v1 := m["apple"] // 获取键值对
v2, ok := m["pear"] // 如果键不存在,ok 的值为 false,v2 的值为该类型的零值
for k, v := range m { // 遍历Map,无序的
fmt.Printf("key=%s, value=%d\n", k, v)
}
delete(m, "banana") // 删除元素
m := make(map[string]int) // 清空元素的方法就是重新make一个map
// 基于 Map 实现 Set
set := make(map[string]bool)
set["Foo"] = true
for k := range set {
fmt.Println(k)
}
delete(set, "Foo")
size := len(set)
exists := set["Foo"]
知识点
数组和切片
- 数组在内存中是一段连续的内存空间,元素的类型和长度都是固定的;
- 切片在内存中由一个指向底层数组的指针、长度和容量组成的,长度表示当前包含的元素个数,容量表示切片可以拓展的最大元素个数。切片
s[x: y]
表示s
中第x
位到第y - 1
位元素截取。
协程
简而言之:用户态的线程
Byte 和 Rune 类型
- byte是uint8的别称,一个值就是一个ASICII码的值,占 1 个字节的英文类字符,使用 byte
- rune是int32的别称,一个值就是一个Unicode字符,占 1 ~ 4 个字节的其他字符,可以使用rune(或者int32),如中文、特殊符号等。