GO语言系列(四)- 内置函数、闭包与高级数据类型

释放双眼,带上耳机,听听看~!

一、内置函数、递归函数、闭包

内置函数

    1. close:主要用来关闭channel
    1. len:用来求长度,比如string、array、slice、map、channel
    1. new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
    1. make:用来分配内存,主要用来分配引用类型,比如chan、map、slice
    1. append:用来追加元素到数组、slice中
    1. panic和recover:用来做错误处理
    1. new和make的区别

GO语言系列(四)- 内置函数、闭包与高级数据类型

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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

内置函数案例

GO语言系列(四)- 内置函数、闭包与高级数据类型GO语言系列(四)- 内置函数、闭包与高级数据类型


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

GO语言系列(四)- 内置函数、闭包与高级数据类型GO语言系列(四)- 内置函数、闭包与高级数据类型


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

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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. 一个函数调用自己,就叫做递归。
    1. 递归设计原则

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

二、数组和切片

数组

    1. 数组:是同一种数据类型的固定长度的序列。
    1. 数组定义:var a [len]int,比如:var a[5]int,一旦定义,长度不能变
    1. 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
    1. 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1


1
2
3
4
5
1for i := 0; i < len(a); i++ {
2}
3for index, v := range a {
4}
5
    1. 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
    1. 数组是值类型,因此改变副本的值,不会改变本身的值

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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

数组示例

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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. 切片相关概念

    1. 切片:切片是数组的一个引用,因此切片是引用类型
    1. 切片的长度可以改变,因此,切片是一个可变的数组
    1. 切片遍历方式和数组一样,可以用len()求长度
    1. cap可以求出slice最大的容量,0 <= len(slice) <= (array),其中array是slice引用的数组
    1. 切片的定义:var 变量名 []类型,比如 var str []string var arr []int

2. 切片的相关语法

    1. 切片初始化:var slice []int = arr[start:end] 包含start到end之间的元素,但不包含end
    1. Var slice []int = arr[0:end]可以简写为 var slice []int=arr[:end]
    1. Var slice []int = arr[start:len(arr)] 可以简写为 var slice[]int = arr[start:]
    1. Var slice []int = arr[0, len(arr)] 可以简写为 var slice[]int = arr[:]
    1. 如果要切片最后一个元素去掉,可以这么写: Slice = slice[:len(slice)-1]

3. 切片的内存布局

GO语言系列(四)- 内置函数、闭包与高级数据类型

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

示例

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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 &quot;fmt&quot;
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(&quot;%p\n&quot;, b)     // 0xc000014238
59    fmt.Printf(&quot;%p\n&quot;, &amp;a[1]) // 0xc000014238
60}
61
62func main() {
63    // testSlice()
64    testSlice2()
65    testSlice3()
66    testSlcie4()
67}
68

切片的用法示例一

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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 &quot;fmt&quot;
4
5func testSlice() {
6    var a [5]int = [...]int{1, 2, 3, 4, 5}
7    s := a[1:]
8    fmt.Println(&quot;a:&quot;, a)
9    s[1] = 100
10    fmt.Printf(&quot;s=%p a[1]=%p\n&quot;, s, &amp;a[1])
11    fmt.Println(&quot;before a:&quot;, 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(&quot;after a:&quot;, a)
21    fmt.Println(s)
22    fmt.Printf(&quot;s=%p a[1]=%p\n&quot;, s, &amp;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 := &quot;hello world&quot;
36    s1 := s[0:5]
37    s2 := s[6:]
38
39    fmt.Println(s1)
40    fmt.Println(s2)
41}
42
43func testModifyString() {
44    s := &quot;我hello world&quot;
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

切片的用法示例二

GO语言系列(四)- 内置函数、闭包与高级数据类型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
27
28
29
30
31
32
33
34
35
36
37
38
39
1package main
2
3import (
4    &quot;fmt&quot;
5    &quot;sort&quot;
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{&quot;abc&quot;, &quot;efg&quot;, &quot;b&quot;, &quot;A&quot;, &quot;eeee&quot;}
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 &lt; 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互换即可

 示例

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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 &quot;fmt&quot;
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(&quot;\t&quot;, k1, v1)
10        }
11    }
12}
13
14func testMap() {
15    var a map[string]string = map[string]string{
16        &quot;key&quot;: &quot;value&quot;,
17    }
18    // a := make(map[string]string, 10)
19    a[&quot;abc&quot;] = &quot;efg&quot;
20    a[&quot;abc1&quot;] = &quot;wew&quot;
21    fmt.Println(a)
22}
23
24func testMap2() {
25    a := make(map[string]map[string]string, 100)
26    a[&quot;key1&quot;] = make(map[string]string)
27    a[&quot;key1&quot;][&quot;key2&quot;] = &quot;val2&quot;
28    a[&quot;key1&quot;][&quot;key3&quot;] = &quot;val3&quot;
29    a[&quot;key1&quot;][&quot;key4&quot;] = &quot;val4&quot;
30    a[&quot;key1&quot;][&quot;key5&quot;] = &quot;val5&quot;
31    a[&quot;key1&quot;][&quot;key6&quot;] = &quot;val6&quot;
32    fmt.Println(a)
33
34}
35
36func modify(a map[string]map[string]string) {
37    _, ok := a[&quot;zhangsan&quot;]
38    if !ok {
39        a[&quot;zhangsan&quot;] = make(map[string]string)
40    }
41    a[&quot;zhangsan&quot;][&quot;pwd&quot;] = &quot;123456&quot;
42    a[&quot;zhangsan&quot;][&quot;nickname&quot;] = &quot;superman&quot;
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[&quot;key1&quot;] = make(map[string]string)
55    a[&quot;key1&quot;][&quot;key2&quot;] = &quot;val2&quot;
56    a[&quot;key1&quot;][&quot;key3&quot;] = &quot;val3&quot;
57    a[&quot;key1&quot;][&quot;key4&quot;] = &quot;val4&quot;
58    a[&quot;key1&quot;][&quot;key5&quot;] = &quot;val5&quot;
59    a[&quot;key2&quot;] = make(map[string]string)
60    a[&quot;key2&quot;][&quot;key22&quot;] = &quot;val22&quot;
61    a[&quot;key2&quot;][&quot;key23&quot;] = &quot;val23&quot;
62    trans(a)
63    delete(a, &quot;key1&quot;)
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示例

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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    &quot;fmt&quot;
5    &quot;sort&quot;
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[&quot;8&quot;] = 10
36    a[&quot;3&quot;] = 11
37    a[&quot;2&quot;] = 12
38    a[&quot;1&quot;] = 13
39    a[&quot;18&quot;] = 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中的包

  • a. golang目前有150个标准的包,覆盖了几乎所有的基础库

  • b. golang.org有所有包的文档,没事都翻翻

2. 线程同步


1
2
3
4
1a. import(“sync”)
2b. 互斥锁, var mu sync.Mutex
3c. 读写锁, var mu sync.RWMutex
4

GO语言系列(四)- 内置函数、闭包与高级数据类型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
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    &quot;fmt&quot;
5    &quot;math/rand&quot;
6    &quot;sync&quot;
7    &quot;sync/atomic&quot;
8    &quot;time&quot;
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 &lt; 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 &lt; 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 &lt; 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(&amp;count, 1)
71            }
72        }(a)
73    }
74
75    time.Sleep(time.Second * 3)
76    fmt.Println(atomic.LoadInt32(&amp;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. 冒泡排序
    1. 选择排序
    1. 插入排序
  • 4.快速排序

参考

GO语言系列(四)- 内置函数、闭包与高级数据类型GO语言系列(四)- 内置函数、闭包与高级数据类型


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 &quot;fmt&quot;
4
5// 冒泡排序:本质上是交换排序的一种
6func bsort(a []int) {
7    for i := 0; i &lt; len(a); i++ {
8        for j := 1; j &lt; len(a)-i; j++ {
9            if a[j] &lt; 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

冒泡排序

GO语言系列(四)- 内置函数、闭包与高级数据类型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
1package main
2
3import &quot;fmt&quot;
4
5// 选择排序
6func ssort(a []int) {
7    for i := 0; i &lt; len(a); i++ {
8        var min int = i
9        for j := i + 1; j &lt; len(a); j++ {
10            if a[min] &gt; 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

选择排序

GO语言系列(四)- 内置函数、闭包与高级数据类型GO语言系列(四)- 内置函数、闭包与高级数据类型


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 &quot;fmt&quot;
4
5// 插入排序, 每次将一个数插入到有序序列当中合适的位置
6func isort(a []int) {
7    for i := 1; i &lt; len(a); i++ {
8        for j := i; j &gt; 0; j-- {
9            if a[j] &gt; 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

插入排序

GO语言系列(四)- 内置函数、闭包与高级数据类型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
27
28
29
30
1package main
2
3import &quot;fmt&quot;
4
5// 快速排序, 一次排序确定一个元素的位置, 使左边的元素都比它小,右边的元素都比它大
6func qsort(a []int, left, right int) {
7    if left &gt;= right {
8        return
9    }
10    val := a[left]
11    // 确定val所在的位置
12    k := left
13    for i := left + 1; i &lt;= right; i++ {
14        if a[i] &lt; 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

快速排序

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++回调函数

2022-1-11 12:36:11

病毒疫情

福建省新型冠状病毒肺炎疫情情况

2020-2-19 8:15:00

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索