一、内置函数、递归函数、闭包
内置函数
-
- close:主要用来关闭channel
-
- len:用来求长度,比如string、array、slice、map、channel
-
- new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
-
- make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
-
- append:用来追加元素到数组、slice中
-
- panic和recover:用来做错误处理
-
- new和make的区别
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| 1package main
2
3import (
4 "errors"
5 "fmt"
6)
7
8func initConfig() (err error) {
9 return errors.New("init config failed")
10}
11
12func test() {
13 /*
14 defer func() {
15 if err := recover(); err != nil {
16 fmt.Println(err)
17 }
18 }()
19 */
20 err := initConfig()
21 if err != nil {
22 panic(err)
23 }
24 return
25}
26
27func main() {
28 test()
29 var i int
30 fmt.Println(i) // 0
31 fmt.Println(&i) // 0xc0000100a8
32
33 j := new(int)
34 *j = 100
35 fmt.Println(j) // 0xc00005a088
36 fmt.Println(*j) // 100
37
38 var a []int // 定义slice
39 a = append(a, 10, 20, 354)
40 a = append(a, a...) // ...可变参数 slice展开
41 fmt.Println(a)
42}
43 |
内置函数案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 1package main
2
3import "fmt"
4
5func test() {
6 s1 := new([]int)
7 fmt.Println(s1)
8
9 s2 := make([]int, 10)
10 fmt.Println(s2)
11
12 *s1 = make([]int, 5)
13 (*s1)[0] = 100
14 s2[0] = 100
15 fmt.Println(s1)
16 fmt.Println(s2)
17 return
18}
19
20func main() {
21 test()
22}
23 |
内置函数2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 1func main() {
2 testError()
3 afterErrorfunc()
4}
5
6func testError() {
7 defer func() {
8 if r := recover(); r != nil {
9 fmt.Println("testError() 遇到错误:", r)
10 }
11 }()
12
13 panic(" \"panic 错误\"")
14 fmt.Println("抛出一个错误后继续执行代码")
15}
16
17func afterErrorfunc() {
18 fmt.Println("遇到错误之后 func ")
19}
20 |
panic和recover
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 27 28 29 30 31
| 1func main() {
2 err := testError()
3 if err != nil {
4 fmt.Println("main 函数得到错误类型:", err)
5 }
6 afterErrorfunc()
7}
8
9func testError() (err error) {
10 defer func() {
11 if r := recover(); r != nil {
12 fmt.Println("testError() 遇到错误:", r)
13 switch x := r.(type) {
14 case string:
15 err = errors.New(x)
16 case error:
17 err = x
18 default:
19 err = errors.New("")
20 }
21 }
22 }()
23 panic(" \"panic 错误\"")
24 fmt.Println("抛出一个错误后继续执行代码")
25 return nil
26}
27
28func afterErrorfunc() {
29 fmt.Println("遇到错误之后 func ")
30}
31 |
panic和recover有返回值
递归函数
1)一个大的问题能够分解成相似的小问题
2)定义好出口条件
案例:递归输出hello,实现阶乘,实现
斐波那契数
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| 1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8// 递归
9func recusive(n int) {
10 fmt.Println("hello", n)
11 time.Sleep(time.Second)
12 if n > 10 {
13 return
14 }
15 recusive(n + 1) // 至少上百万上千万次递归
16}
17
18// 阶乘
19func factor(n int) int {
20 if n == 1 {
21 return 1
22 }
23 return factor(n-1) * n
24}
25
26//斐波那契数
27func fab(n int) int {
28 if n <= 1 {
29 return 1
30 }
31 return fab(n-1) + fab(n-2)
32}
33
34func main() {
35 // fmt.Println(factor(5))
36 recusive(0)
37 // for i := 0; i < 10; i++ {
38 // fmt.Println(fab(i))
39 // }
40}
41 |
闭包
闭包:一个函数和与其相关的引用环境组合而成的实体
案例:Adder和为文件名添加后缀
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 27 28 29 30 31 32 33 34 35 36 37 38 39
| 1package main
2
3import (
4 "fmt"
5 "strings"
6)
7
8func Adder() func(int) int {
9 var x int
10 return func(d int) int {
11 x += d
12 return x
13 }
14}
15
16func makeSuffix(suffix string) func(string) string {
17 return func(name string) string {
18 if strings.HasSuffix(name, suffix) == false {
19 return name + suffix
20 }
21 return name
22 }
23}
24
25func main() {
26 f := Adder()
27 fmt.Println(f(1))
28 fmt.Println(f(100))
29 fmt.Println(f(1000))
30
31 f1 := makeSuffix(".bmp")
32 fmt.Println(f1("test"))
33 fmt.Println(f1("pic"))
34
35 f2 := makeSuffix(".jpg")
36 fmt.Println(f2("test"))
37 fmt.Println(f2("pic"))
38}
39 |
二、数组和切片
数组
-
- 数组:是同一种数据类型的固定长度的序列。
-
- 数组定义:var a [len]int,比如:var a[5]int,一旦定义,长度不能变
-
- 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
-
-
数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1
1 2 3 4 5
| 1for i := 0; i < len(a); i++ {
2}
3for index, v := range a {
4}
5 |
-
- 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
-
- 数组是值类型,因此改变副本的值,不会改变本身的值
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| 1package main
2
3import "fmt"
4
5func test1() {
6 var a [10]int
7 a[0] = 10
8 a[9] = 100
9 fmt.Println(a)
10
11 for i := 0; i < len(a); i++ {
12 fmt.Println(a[i])
13 }
14 for index, val := range a {
15 fmt.Printf("a[%d]=%d\n", index, val)
16 }
17}
18
19func test2() {
20 var a [10]int
21 b := a
22 b[0] = 100
23 fmt.Println(a)
24}
25
26func test3(arr *[5]int) {
27 (*arr)[0] = 1000
28}
29
30func main() {
31 test1()
32 test2()
33 var a [5]int
34 test3(&a)
35 fmt.Println(a)
36}
37
38/*
39[10 0 0 0 0 0 0 0 0 100]
4010
410
420
430
440
450
460
470
480
49100
50a[0]=10
51a[1]=0
52a[2]=0
53a[3]=0
54a[4]=0
55a[5]=0
56a[6]=0
57a[7]=0
58a[8]=0
59a[9]=100
60[0 0 0 0 0 0 0 0 0 0]
61[1000 0 0 0 0]
62*/
63 |
数组示例一
数组初始化
1 2 3 4 5
| 1a. var age0 [5]int = [5]int{1,2,3}
2b. var age1 = [5]int{1,2,3,4,5}
3c. var age2 = […]int{1,2,3,4,5,6}
4d. var str = [5]string{3:”hello world”, 4:”tom”}
5 |
多维数组
1 2 3
| 1a. var age [5][3]int
2b. var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
3 |
多维数组遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8
9 var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
10
11 for k1, v1 := range f {
12 for k2, v2 := range v1 {
13 fmt.Printf("(%d,%d)=%d ", k1, k2, v2)
14 }
15 fmt.Println()
16 }
17}
18 |
数组示例
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| 1package main
2
3import (
4 "fmt"
5)
6
7func fab(n int) {
8 var a []int
9 a = make([]int, n)
10
11 a[0] = 1
12 a[1] = 1
13
14 for i := 2; i < n; i++ {
15 a[i] = a[i-1] + a[i-2]
16 }
17
18 for _, v := range a {
19 fmt.Println(v)
20 }
21}
22
23func testArray() {
24 var a [5]int = [5]int{1, 2, 3, 4, 5}
25 var a1 = [5]int{1, 2, 3, 4, 5}
26 var a2 = [...]int{38, 283, 48, 38, 348, 387, 484}
27 var a3 = [...]int{1: 100, 3: 200}
28 var a4 = [...]string{1: "hello", 3: "world"}
29
30 fmt.Println(a)
31 fmt.Println(a1)
32 fmt.Println(a2)
33 fmt.Println(a3)
34 fmt.Println(a4)
35 /*
36 [1 2 3 4 5]
37 [1 2 3 4 5]
38 [38 283 48 38 348 387 484]
39 [0 100 0 200]
40 [ hello world]
41 */
42}
43
44func testArray2() {
45 var a [2][5]int = [...][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}
46
47 for row, v := range a {
48 for col, v1 := range v {
49 fmt.Printf("(%d,%d)=%d ", row, col, v1)
50 }
51 fmt.Println()
52 }
53}
54
55func main() {
56 fab(10)
57 testArray()
58 testArray2()
59}
60 |
数组示例二
切片
1. 切片相关概念
-
- 切片:切片是数组的一个引用,因此切片是引用类型
-
- 切片的长度可以改变,因此,切片是一个可变的数组
-
- 切片遍历方式和数组一样,可以用len()求长度
-
- cap可以求出slice最大的容量,0 <= len(slice) <= (array),其中array是slice引用的数组
-
- 切片的定义:var 变量名 []类型,比如 var str []string var arr []int
2. 切片的相关语法
-
- 切片初始化:var slice []int = arr[start:end] 包含start到end之间的元素,但不包含end
-
- Var slice []int = arr[0:end]可以简写为 var slice []int=arr[:end]
-
- Var slice []int = arr[start:len(arr)] 可以简写为 var slice[]int = arr[start:]
-
- Var slice []int = arr[0, len(arr)] 可以简写为 var slice[]int = arr[:]
-
- 如果要切片最后一个元素去掉,可以这么写: Slice = slice[:len(slice)-1]
3. 切片的内存布局
4. 通过make来创建切片
1 2 3 4
| 1var slice []type = make([]type, len)
2slice := make([]type, len)
3slice := make([]type, len, cap)
4 |
5. 用append内置函数操作切片
1 2 3 4 5
| 1slice = append(slice, 10)
2var a = []int{1,2,3}
3var b = []int{4,5,6}
4a = append(a, b…)
5 |
6. For range 遍历切片
1 2 3
| 1for index, val := range slice {
2}
3 |
7. 切片resize
1 2 3 4
| 1var a = []int {1,3,4,5}
2b := a[1:2]
3b = b[0:3]
4 |
8. 切片拷贝
1 2 3 4 5 6 7 8 9 10 11 12
| 1s1 := []int{1,2,3,4,5}
2
3s2 := make([]int, 10)
4
5copy(s2, s1)
6
7s3 := []int{1,2,3}
8
9s3 = append(s3, s2…)
10
11s3 = append(s3, 4,5,6)
12 |
9. string与slice
string底层就是一个byte的数组,因此,也可以进行切片操作
1 2 3 4 5 6
| 1str := “hello world”
2s1 := str[0:5]
3fmt.Println(s1)
4s2 := str[5:]
5fmt.Println(s2)
6 |
10. string的底层布局
11. 如何改变string中的字符值?
string本身是不可变的,因此要改变string中字符,需要如下操作:
1 2 3 4 5
| 1str := “hello world”
2s := []byte(str)
3s[0] = ‘o’
4str = string(s)
5 |
12. 排序和查找操作
排序操作主要都在 sort包中,导入就可以使用了
1 2 3 4 5 6
| 1sort.Ints对整数进行排序, sort.Strings对字符串进行排序, sort.Float64s对
2浮点数进行排序.
3sort.SearchInts(a []int, b int) 从数组a中查找b,前提是a必须有序
4sort.SearchFloats(a []float64, b float64) 从数组a中查找b,前提是a必须有序
5sort.SearchStrings(a []string, b string) 从数组a中查找b,前提是a必须有序
6 |
示例
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| 1package main
2
3import "fmt"
4
5type slice struct {
6 ptr *[100]int
7 len int
8 cap int
9}
10
11func make1(s slice, cap int) slice {
12 s.ptr = new([100]int)
13 s.cap = cap
14 s.len = 0
15 return s
16}
17
18func testSlice() {
19 var slice []int
20 var arr [5]int = [...]int{1, 2, 3, 4, 5}
21
22 slice = arr[:]
23 fmt.Println(slice)
24 fmt.Println(arr[2:4]) // [3,4]
25 fmt.Println(arr[2:]) // [3,4,5]
26 fmt.Println(arr[0:1]) // [1]
27 fmt.Println(arr[:len(arr)-1])
28}
29
30func modify(s slice) {
31 s.ptr[1] = 1000
32}
33
34func testSlice2() {
35 var s1 slice
36 s1 = make1(s1, 10)
37
38 s1.ptr[0] = 100
39 modify(s1)
40
41 fmt.Println(s1.ptr)
42}
43
44func modify1(a []int) {
45 a[1] = 1000
46}
47
48func testSlice3() {
49 var b []int = []int{1, 2, 3, 4}
50 modify1(b)
51 fmt.Println(b)
52}
53
54func testSlcie4() {
55 var a = [10]int{1, 2, 3, 4}
56
57 b := a[1:5]
58 fmt.Printf("%p\n", b) // 0xc000014238
59 fmt.Printf("%p\n", &a[1]) // 0xc000014238
60}
61
62func main() {
63 // testSlice()
64 testSlice2()
65 testSlice3()
66 testSlcie4()
67}
68 |
切片的用法示例一
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| 1package main
2
3import "fmt"
4
5func testSlice() {
6 var a [5]int = [...]int{1, 2, 3, 4, 5}
7 s := a[1:]
8 fmt.Println("a:", a)
9 s[1] = 100
10 fmt.Printf("s=%p a[1]=%p\n", s, &a[1])
11 fmt.Println("before a:", a)
12
13 s = append(s, 10)
14 s = append(s, 10)
15 s = append(s, 10)
16 s = append(s, 10)
17 s = append(s, 10)
18
19 s[1] = 1000
20 fmt.Println("after a:", a)
21 fmt.Println(s)
22 fmt.Printf("s=%p a[1]=%p\n", s, &a[1])
23}
24
25func testCopy() {
26 var a []int = []int{1, 2, 3, 4, 5}
27 b := make([]int, 10)
28
29 copy(b, a)
30
31 fmt.Println(b)
32}
33
34func testString() {
35 s := "hello world"
36 s1 := s[0:5]
37 s2 := s[6:]
38
39 fmt.Println(s1)
40 fmt.Println(s2)
41}
42
43func testModifyString() {
44 s := "我hello world"
45 s1 := []rune(s)
46
47 s1[0] = 200
48 s1[1] = 128
49 s1[2] = 256
50 str := string(s1)
51 fmt.Println(str)
52}
53
54func main() {
55 // testSlice()
56 testCopy()
57 testString()
58 testModifyString()
59}
60 |
切片的用法示例二
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 27 28 29 30 31 32 33 34 35 36 37 38 39
| 1package main
2
3import (
4 "fmt"
5 "sort"
6)
7
8func testIntSort() {
9 var a = [...]int{1, 8, 43, 2, 456}
10 sort.Ints(a[:])
11 fmt.Println(a)
12}
13
14func testStrings() {
15 var a = [...]string{"abc", "efg", "b", "A", "eeee"}
16 sort.Strings(a[:])
17
18 fmt.Println(a)
19}
20
21func testFloat() {
22 var a = [...]float64{2.3, 0.8, 28.2, 392342.2, 0.6}
23 sort.Float64s(a[:])
24 fmt.Println(a)
25}
26
27func testIntSearch() {
28 var a = [...]int{1, 8, 43, 2, 456}
29 index := sort.SearchInts(a[:], 2)
30 fmt.Println(index)
31}
32
33func main() {
34 testIntSort()
35 testStrings()
36 testFloat()
37 testIntSearch()
38}
39 |
切片的用法示例三
三、map数据结构
1.map简介
key-value的数据结构,又叫字典或关联数组
a.声明
1 2 3 4 5 6
| 1var map1 map[keytype]valuetype
2var a map[string]string
3var a map[string]int
4var a map[int]string
5var a map[string]map[string]string
6 |
声明是不会分配内存的,初始化需要make
2. map相关操作
1 2 3 4 5 6 7 8 9 10
| 1var a map[string]string = map[string]string{“hello”: “world”}
2a = make(map[string]string, 10)
3a[“hello”] = “world” // 插入和更新
4Val, ok := a[“hello”] //查找
5for k, v := range a { //遍历
6fmt.Println(k,v)
7}
8delete(a, “hello”) // 删除
9len(a) // 长度
10 |
3. map是引用类型
1 2 3 4
| 1func modify(a map[string]int) {
2a[“one”] = 134
3}
4 |
4. slice of map
1 2 3 4 5
| 1Items := make([]map[int][int], 5)
2For I := 0; I < 5; i++ {
3items[i] = make(map[int][int])
4}
5 |
5. map排序
1 2 3
| 1a. 先获取所有key,把key进行排序
2b. 按照排序好的key,进行遍历
3 |
6. Map反转
- a. 初始化另外一个map,把key、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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| 1package main
2
3import "fmt"
4
5func trans(a map[string]map[string]string) {
6 for k, v := range a {
7 fmt.Println(k)
8 for k1, v1 := range v {
9 fmt.Println("\t", k1, v1)
10 }
11 }
12}
13
14func testMap() {
15 var a map[string]string = map[string]string{
16 "key": "value",
17 }
18 // a := make(map[string]string, 10)
19 a["abc"] = "efg"
20 a["abc1"] = "wew"
21 fmt.Println(a)
22}
23
24func testMap2() {
25 a := make(map[string]map[string]string, 100)
26 a["key1"] = make(map[string]string)
27 a["key1"]["key2"] = "val2"
28 a["key1"]["key3"] = "val3"
29 a["key1"]["key4"] = "val4"
30 a["key1"]["key5"] = "val5"
31 a["key1"]["key6"] = "val6"
32 fmt.Println(a)
33
34}
35
36func modify(a map[string]map[string]string) {
37 _, ok := a["zhangsan"]
38 if !ok {
39 a["zhangsan"] = make(map[string]string)
40 }
41 a["zhangsan"]["pwd"] = "123456"
42 a["zhangsan"]["nickname"] = "superman"
43 return
44}
45
46func testMap3() {
47 a := make(map[string]map[string]string, 100)
48 modify(a)
49 fmt.Println(a)
50}
51
52func testMap4() {
53 a := make(map[string]map[string]string, 100)
54 a["key1"] = make(map[string]string)
55 a["key1"]["key2"] = "val2"
56 a["key1"]["key3"] = "val3"
57 a["key1"]["key4"] = "val4"
58 a["key1"]["key5"] = "val5"
59 a["key2"] = make(map[string]string)
60 a["key2"]["key22"] = "val22"
61 a["key2"]["key23"] = "val23"
62 trans(a)
63 delete(a, "key1")
64 fmt.Println()
65 trans(a)
66}
67
68func testMap5() {
69 var a []map[int]int
70 a = make([]map[int]int, 5)
71
72 if a[0] == nil {
73 a[0] = make(map[int]int)
74 }
75 a[0][10] = 10
76 fmt.Println(a)
77}
78
79func main() {
80 testMap()
81 testMap2()
82 testMap3()
83 testMap4()
84 testMap5()
85}
86 |
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| 1package main
2
3import (
4 "fmt"
5 "sort"
6)
7
8func testMapSort() {
9 var a map[int]int
10 a = make(map[int]int, 5)
11
12 a[8] = 10
13 a[3] = 10
14 a[2] = 10
15 a[1] = 10
16 a[18] = 10
17
18 var keys []int
19 for k, _ := range a {
20 keys = append(keys, k)
21 // fmt.Println(k, v)
22 }
23 sort.Ints(keys)
24 for _, v := range keys {
25 fmt.Println(v, a[v])
26 }
27}
28
29func testMapSort2() {
30 var a map[string]int
31 var b map[int]string
32
33 a = make(map[string]int, 5)
34 b = make(map[int]string, 5)
35 a["8"] = 10
36 a["3"] = 11
37 a["2"] = 12
38 a["1"] = 13
39 a["18"] = 14
40
41 for k, v := range a {
42 b[v] = k
43 }
44 fmt.Println(b)
45}
46
47func main() {
48 testMapSort()
49 testMapSort2()
50}
51 |
map示例2
四、包
1. golang中的包
2. 线程同步
1 2 3 4
| 1a. import(“sync”)
2b. 互斥锁, var mu sync.Mutex
3c. 读写锁, var mu sync.RWMutex
4 |
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| 1package main
2
3import (
4 "fmt"
5 "math/rand"
6 "sync"
7 "sync/atomic"
8 "time"
9)
10
11var rwLock *sync.RWMutex
12
13func testLock() {
14
15 var a map[int]int
16 a = make(map[int]int, 5)
17
18 a[8] = 10
19 a[3] = 10
20 a[2] = 10
21 a[1] = 10
22 a[18] = 10
23
24 for i := 0; i < 2; i++ {
25 go func(b map[int]int) {
26 rwLock.RLock()
27 b[8] = rand.Intn(100)
28 rwLock.Unlock()
29 }(a)
30 }
31
32 rwLock.RLock()
33 fmt.Println(a)
34 rwLock.Unlock()
35}
36
37func testRWLock() {
38 // var rwLock myLocker = new(sync.RWMutex)
39 // var rwLock sync.RWMutex
40 // var rwLock sync.Mutex
41 var a map[int]int
42 a = make(map[int]int, 5)
43
44 var count int32
45
46 a[8] = 10
47 a[3] = 10
48 a[2] = 10
49 a[1] = 10
50 a[18] = 10
51
52 for i := 0; i < 2; i++ {
53 go func(b map[int]int) {
54 rwLock.Lock()
55 // lock.Lock()
56 b[8] = rand.Intn(100)
57 time.Sleep(time.Millisecond)
58 rwLock.Unlock()
59 // lock.Unlock()
60 }(a)
61 }
62
63 for i := 0; i < 100; i++ {
64 go func(b map[int]int) {
65 for {
66 rwLock.Lock()
67 time.Sleep(time.Millisecond)
68 // fmt.Println(a)
69 rwLock.Unlock()
70 atomic.AddInt32(&count, 1)
71 }
72 }(a)
73 }
74
75 time.Sleep(time.Second * 3)
76 fmt.Println(atomic.LoadInt32(&count))
77}
78
79func main() {
80 rwLock = new(sync.RWMutex)
81 // testLock()
82 testRWLock()
83}
84 |
线程同步锁示例
3. go get安装第三方包
1 2
| 1go get github.com/go-sql-driver/mysql
2 |
本节作业
参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 1package main
2
3import "fmt"
4
5// 冒泡排序:本质上是交换排序的一种
6func bsort(a []int) {
7 for i := 0; i < len(a); i++ {
8 for j := 1; j < len(a)-i; j++ {
9 if a[j] < a[j-1] {
10 a[j], a[j-1] = a[j-1], a[j]
11 }
12 }
13 }
14}
15
16func main() {
17 b := [...]int{8, 7, 4, 5, 3, 2, 1}
18 bsort(b[:])
19 fmt.Println(b)
20}
21 |
冒泡排序
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
| 1package main
2
3import "fmt"
4
5// 选择排序
6func ssort(a []int) {
7 for i := 0; i < len(a); i++ {
8 var min int = i
9 for j := i + 1; j < len(a); j++ {
10 if a[min] > a[j] {
11 min = j
12 }
13 }
14 if min != i {
15 a[i], a[min] = a[min], a[i]
16 }
17 }
18}
19
20func main() {
21 b := [...]int{8, 7, 4, 5, 3, 2, 1}
22 ssort(b[:])
23 fmt.Println(b)
24}
25 |
选择排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 1package main
2
3import "fmt"
4
5// 插入排序, 每次将一个数插入到有序序列当中合适的位置
6func isort(a []int) {
7 for i := 1; i < len(a); i++ {
8 for j := i; j > 0; j-- {
9 if a[j] > a[j-1] {
10 break
11 }
12 a[j], a[j-1] = a[j-1], a[j]
13 }
14 }
15}
16
17func main() {
18 b := [...]int{8, 7, 4, 5, 3, 2, 1}
19 isort(b[:])
20 fmt.Println(b)
21}
22 |
插入排序
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 27 28 29 30
| 1package main
2
3import "fmt"
4
5// 快速排序, 一次排序确定一个元素的位置, 使左边的元素都比它小,右边的元素都比它大
6func qsort(a []int, left, right int) {
7 if left >= right {
8 return
9 }
10 val := a[left]
11 // 确定val所在的位置
12 k := left
13 for i := left + 1; i <= right; i++ {
14 if a[i] < val {
15 a[k] = a[i]
16 a[i] = a[k+1]
17 k++
18 }
19 }
20 a[k] = val
21 qsort(a, left, k-1)
22 qsort(a, k+1, right)
23}
24
25func main() {
26 b := [...]int{8, 7, 4, 5, 3, 2, 1}
27 qsort(b[:], 0, len(b)-1)
28 fmt.Println(b)
29}
30 |
快速排序