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

内置函数

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

  1. package main
  2.  
  3. import (
  4. "errors"
  5. "fmt"
  6. )
  7.  
  8. func initConfig() (err error) {
  9. return errors.New("init config failed")
  10. }
  11.  
  12. func 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.  
  27. func 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. }

内置函数案例

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func 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.  
  20. func main() {
  21. test()
  22. }

内置函数2

  1. func main() {
  2. testError()
  3. afterErrorfunc()
  4. }
  5.  
  6. func 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.  
  17. func afterErrorfunc() {
  18. fmt.Println("遇到错误之后 func ")
  19. }

panic和recover

  1. func main() {
  2. err := testError()
  3. if err != nil {
  4. fmt.Println("main 函数得到错误类型:", err)
  5. }
  6. afterErrorfunc()
  7. }
  8.  
  9. func 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.  
  28. func afterErrorfunc() {
  29. fmt.Println("遇到错误之后 func ")
  30. }

panic和recover有返回值

递归函数

  • 1. 一个函数调用自己,就叫做递归。

  • 2. 递归设计原则

1)一个大的问题能够分解成相似的小问题

2)定义好出口条件

 案例:递归输出hello,实现阶乘,实现斐波那契数

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "time"
  6. )
  7.  
  8. // 递归
  9. func 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. // 阶乘
  19. func factor(n int) int {
  20. if n == 1 {
  21. return 1
  22. }
  23. return factor(n-1) * n
  24. }
  25.  
  26. //斐波那契数
  27. func fab(n int) int {
  28. if n <= 1 {
  29. return 1
  30. }
  31. return fab(n-1) + fab(n-2)
  32. }
  33.  
  34. func main() {
  35. // fmt.Println(factor(5))
  36. recusive(0)
  37. // for i := 0; i < 10; i++ {
  38. // fmt.Println(fab(i))
  39. // }
  40. }

 闭包

闭包:一个函数和与其相关的引用环境组合而成的实体

案例:Adder和为文件名添加后缀

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "strings"
  6. )
  7.  
  8. func Adder() func(int) int {
  9. var x int
  10. return func(d int) int {
  11. x += d
  12. return x
  13. }
  14. }
  15.  
  16. func 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.  
  25. func 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. }

二、数组和切片

数组

  • 1. 数组:是同一种数据类型的固定长度的序列。
  • 2. 数组定义:var a [len]int,比如:var a[5]int,一旦定义,长度不能变
  • 3. 长度是数组类型的一部分,因此,var a[5] int和var a[10]int是不同的类型
  • 4. 数组可以通过下标进行访问,下标是从0开始,最后一个元素下标是:len-1
  1. for i := 0; i < len(a); i++ {
  2. }
  3. for index, v := range a {
  4. }
  • 5. 访问越界,如果下标在数组合法范围之外,则触发访问越界,会panic
  • 6. 数组是值类型,因此改变副本的值,不会改变本身的值
  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func 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.  
  19. func test2() {
  20. var a [10]int
  21. b := a
  22. b[0] = 100
  23. fmt.Println(a)
  24. }
  25.  
  26. func test3(arr *[5]int) {
  27. (*arr)[0] = 1000
  28. }
  29.  
  30. func 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]
  40. 10
  41. 0
  42. 0
  43. 0
  44. 0
  45. 0
  46. 0
  47. 0
  48. 0
  49. 100
  50. a[0]=10
  51. a[1]=0
  52. a[2]=0
  53. a[3]=0
  54. a[4]=0
  55. a[5]=0
  56. a[6]=0
  57. a[7]=0
  58. a[8]=0
  59. a[9]=100
  60. [0 0 0 0 0 0 0 0 0 0]
  61. [1000 0 0 0 0]
  62. */

数组示例一

数组初始化

  1. a. var age0 [5]int = [5]int{1,2,3}
  2. b. var age1 = [5]int{1,2,3,4,5}
  3. c. var age2 = […]int{1,2,3,4,5,6}
  4. d. var str = [5]string{3:”hello world”, 4:”tom”}

多维数组

  1. a. var age [5][3]int
  2. b. var f [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}  

多维数组遍历

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func 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. } 

数组示例

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func 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.  
  23. func 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.  
  44. func 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.  
  55. func main() {
  56. fab(10)
  57. testArray()
  58. testArray2()
  59. }

数组示例二

切片

1. 切片相关概念

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

2. 切片的相关语法

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

3. 切片的内存布局

4. 通过make来创建切片

  1. var slice []type = make([]type, len)
  2. slice := make([]type, len)
  3. slice := make([]type, len, cap)

5. 用append内置函数操作切片

  1. slice = append(slice, 10)
  2. var a = []int{1,2,3}
  3. var b = []int{4,5,6}
  4. a = append(a, b…)

6. For range 遍历切片

  1. for index, val := range slice {
  2. }

7. 切片resize

  1. var a = []int {1,3,4,5}
  2. b := a[1:2]
  3. b = b[0:3]

8. 切片拷贝

  1. s1 := []int{1,2,3,4,5}
  2.  
  3. s2 := make([]int, 10)
  4.  
  5. copy(s2, s1)
  6.  
  7. s3 := []int{1,2,3}
  8.  
  9. s3 = append(s3, s2…)
  10.  
  11. s3 = append(s3, 4,5,6)

9. string与slice

  string底层就是一个byte的数组,因此,也可以进行切片操作

  1. str := hello world
  2. s1 := str[0:5]
  3. fmt.Println(s1)
  4. s2 := str[5:]
  5. fmt.Println(s2)

10. string的底层布局

11. 如何改变string中的字符值?

string本身是不可变的,因此要改变string中字符,需要如下操作:

  1. str := hello world
  2. s := []byte(str)
  3. s[0] = o
  4. str = string(s)

12. 排序和查找操作

排序操作主要都在 sort包中,导入就可以使用了

  1. sort.Ints对整数进行排序, sort.Strings对字符串进行排序, sort.Float64s
  2. 浮点数进行排序.
  3. sort.SearchInts(a []int, b int) 从数组a中查找b,前提是a必须有序
  4. sort.SearchFloats(a []float64, b float64) 从数组a中查找b,前提是a必须有序
  5. sort.SearchStrings(a []string, b string) 从数组a中查找b,前提是a必须有序

示例

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. type slice struct {
  6. ptr *[100]int
  7. len int
  8. cap int
  9. }
  10.  
  11. func 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.  
  18. func 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.  
  30. func modify(s slice) {
  31. s.ptr[1] = 1000
  32. }
  33.  
  34. func 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.  
  44. func modify1(a []int) {
  45. a[1] = 1000
  46. }
  47.  
  48. func testSlice3() {
  49. var b []int = []int{1, 2, 3, 4}
  50. modify1(b)
  51. fmt.Println(b)
  52. }
  53.  
  54. func 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.  
  62. func main() {
  63. // testSlice()
  64. testSlice2()
  65. testSlice3()
  66. testSlcie4()
  67. }

切片的用法示例一

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func 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.  
  25. func 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.  
  34. func 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.  
  43. func 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.  
  54. func main() {
  55. // testSlice()
  56. testCopy()
  57. testString()
  58. testModifyString()
  59. }

切片的用法示例二

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. func testIntSort() {
  9. var a = [...]int{1, 8, 43, 2, 456}
  10. sort.Ints(a[:])
  11. fmt.Println(a)
  12. }
  13.  
  14. func testStrings() {
  15. var a = [...]string{"abc", "efg", "b", "A", "eeee"}
  16. sort.Strings(a[:])
  17.  
  18. fmt.Println(a)
  19. }
  20.  
  21. func 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.  
  27. func testIntSearch() {
  28. var a = [...]int{1, 8, 43, 2, 456}
  29. index := sort.SearchInts(a[:], 2)
  30. fmt.Println(index)
  31. }
  32.  
  33. func main() {
  34. testIntSort()
  35. testStrings()
  36. testFloat()
  37. testIntSearch()
  38. }

切片的用法示例三

三、map数据结构

1.map简介

key-value的数据结构,又叫字典或关联数组
a.声明

  1. var map1 map[keytype]valuetype
  2. var a map[string]string
  3. var a map[string]int
  4. var a map[int]string
  5. var a map[string]map[string]string

声明是不会分配内存的,初始化需要make

2. map相关操作

  1. var a map[string]string = map[string]string{“hello”: world”}
  2. a = make(map[string]string, 10)
  3. a[“hello”] = world // 插入和更新
  4. Val, ok := a[“hello”] //查找
  5. for k, v := range a { //遍历
  6. fmt.Println(k,v)
  7. }
  8. delete(a, hello”) // 删除
  9. len(a) // 长度

3. map是引用类型

  1. func modify(a map[string]int) {
  2. a[“one”] = 134
  3. }

4. slice of map

  1. Items := make([]map[int][int], 5)
  2. For I := 0; I < 5; i++ {
  3. items[i] = make(map[int][int])
  4. }

5. map排序

  1. a. 先获取所有key,把key进行排序
  2. b. 按照排序好的key,进行遍历

6. Map反转

  • a. 初始化另外一个map,把key、value互换即可

示例

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func 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.  
  14. func 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.  
  24. func 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.  
  36. func 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"] = ""
  42. a["zhangsan"]["nickname"] = "superman"
  43. return
  44. }
  45.  
  46. func testMap3() {
  47. a := make(map[string]map[string]string, 100)
  48. modify(a)
  49. fmt.Println(a)
  50. }
  51.  
  52. func 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.  
  68. func 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.  
  79. func main() {
  80. testMap()
  81. testMap2()
  82. testMap3()
  83. testMap4()
  84. testMap5()
  85. }

map示例

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "sort"
  6. )
  7.  
  8. func 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.  
  29. func 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[""] = 10
  36. a[""] = 11
  37. a[""] = 12
  38. a[""] = 13
  39. a[""] = 14
  40.  
  41. for k, v := range a {
  42. b[v] = k
  43. }
  44. fmt.Println(b)
  45. }
  46.  
  47. func main() {
  48. testMapSort()
  49. testMapSort2()
  50. }

map示例2

四、包

1. golang中的包

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

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

2. 线程同步

  1. a. import(“sync”)
  2. b. 互斥锁, var mu sync.Mutex
  3. c. 读写锁, var mu sync.RWMutex
  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "math/rand"
  6. "sync"
  7. "sync/atomic"
  8. "time"
  9. )
  10.  
  11. var rwLock *sync.RWMutex
  12.  
  13. func 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.  
  37. func 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.  
  79. func main() {
  80. rwLock = new(sync.RWMutex)
  81. // testLock()
  82. testRWLock()
  83. }

线程同步锁示例

3. go get安装第三方包

  1. go get github.com/go-sql-driver/mysql 

本节作业

  • 1. 冒泡排序

  • 2. 选择排序

  • 3. 插入排序

  • 4.快速排序

参考

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. // 冒泡排序:本质上是交换排序的一种
  6. func 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.  
  16. func main() {
  17. b := [...]int{8, 7, 4, 5, 3, 2, 1}
  18. bsort(b[:])
  19. fmt.Println(b)
  20. }

冒泡排序

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. // 选择排序
  6. func 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.  
  20. func main() {
  21. b := [...]int{8, 7, 4, 5, 3, 2, 1}
  22. ssort(b[:])
  23. fmt.Println(b)
  24. }

选择排序

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. // 插入排序, 每次将一个数插入到有序序列当中合适的位置
  6. func 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.  
  17. func main() {
  18. b := [...]int{8, 7, 4, 5, 3, 2, 1}
  19. isort(b[:])
  20. fmt.Println(b)
  21. }

插入排序

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. // 快速排序, 一次排序确定一个元素的位置, 使左边的元素都比它小,右边的元素都比它大
  6. func 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.  
  25. func main() {
  26. b := [...]int{8, 7, 4, 5, 3, 2, 1}
  27. qsort(b[:], 0, len(b)-1)
  28. fmt.Println(b)
  29. }

快速排序

GO语言系列(四)- 内置函数、闭包与高级数据类型的更多相关文章

  1. 12.Python略有小成(生成器,推导式,内置函数,闭包)

    Python(生成器,推导式,内置函数,闭包) 一.生成器初始 生成器的本质就是迭代器,python社区中认为生成器与迭代器是一种 生成器与迭代器的唯一区别,生成器是我们自己用python代码构建成的 ...

  2. Python函数05/内置函数/闭包

    Python函数05/内置函数/闭包 目录 Python函数05/内置函数/闭包 内容大纲 1.内置函数(二) 2.匿名函数及内置函数(重要) 3.闭包 4.今日总结 5.今日练习 内容大纲 1.内置 ...

  3. 面向对象 反射 和item系列和内置函数和__getattr__和__setattr__

    反射 反射主要用在网络编程中, python面向对象的反射:通过字符串的形式操作对象相关的属性.python的一切事物都是对象. 反射就是通过字符串的形式,导入模块:通过字符串的形式,去模块寻找指定函 ...

  4. go:内置函数 | 闭包 | 数组 | 切片 | 排序 | map | 锁

    内置函数 1.close: 主要是用来关闭channel 2.len:用来求长度,比如string.array.slice.map.channel 3.new与make都是用来分配内存 new用来分配 ...

  5. Python系列-python内置函数

    abs(x) 返回数字的绝对值,参数可以是整数.也可以是浮点数.如果是复数,则返回它的大小 all(iterable) 对参数中的所有元素进行迭代,如果所有的元素都是True,则返回True,函数等价 ...

  6. PYTHON语言之常用内置函数

    一 写在开头本文列举了一些常用的python内置函数.完整详细的python内置函数列表请参见python文档的Built-in Functions章节. 二 python常用内置函数请注意,有关内置 ...

  7. C语言基础:内置函数的调用

    #include<stdio.h>#include<math.h>#include<stdlib.h>#include<ctype.h>#include ...

  8. Python 内置函数sorted()在高级用法

    对于Python内置函数sorted(),先拿来跟list(列表)中的成员函数list.sort()进行下对比.在本质上,list的排序和内建函数sorted的排序是差不多的,连参数都基本上是一样的. ...

  9. python 使用内置函数sorted对各种数据类型进行排序

    python有两个内置的函数用于实现排序,一个是list.sort()函数,一个是sorted()函数. 区别1:list.sort()函数只能处理list类型数据的排序:sorted()则可以处理多 ...

  10. 【LESS系列】内置函数说明

    本文转自 http://www.cnblogs.com/zfc2201/p/3493335.html escape(@string); // 通过 URL-encoding 编码字符串 e(@stri ...

随机推荐

  1. python 之 查找某目录中最新的文件

    记录一下这个方法,感觉很有用!>.< import os def find_newest_file(path_file): lists = os.listdir(path_file) li ...

  2. 上传本地文件到GitHub上

    问题解决 今天在windows上上传本地文件到github,出现用户名和仓库不匹配的情况,解决方式如下: 打开控制面板,选择用户账户 把该删除的账户删除一下就行了. 上传文件的步骤如下: 将上传的文件 ...

  3. SQL NULL 值

    NULL 值是遗漏的未知数据. 默认地,表的列可以存放 NULL 值. 本章讲解 IS NULL 和 IS NOT NULL 操作符. SQL NULL 值 如果表中的某个列是可选的,那么我们可以在不 ...

  4. 文本分类实战(二)—— textCNN 模型

    1 大纲概述 文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类.总共有以下系列: word2vec预训练词向量 te ...

  5. 监控glusterfs

    监控集群状态 [4ajr@elk1 scripts]$ cat glusterfs_peer_status.sh #!/bin/bash peer_status=`sudo gluster peer ...

  6. Linux soft lockup分析

    关键词:watchdog.soft lockup.percpu thread.lockdep等. 近日遇到一个soft lockup问题,打印类似“[ 56.032356] NMI watchdog: ...

  7. 如何用ABP框架快速完成项目(6) - 用ABP一个人快速完成项目(2) - 使用多个成熟控件框架

    正如我在<office365的开发者训练营,免费,在微软广州举办>课程里面所讲的, 站在巨人的肩膀上的其中一项就是, 尽量使用别人成熟的框架. 其中也包括了控件框架   abp和52abp ...

  8. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  9. mybatis 使用缓存策略

    mybatis中默认开启缓存 1.mybatis中,默认是开启缓存的,缓存的是一个statement对象. 不同情况下是否会使用缓存 同一个SqlSession对象,重复调用同一个id的<sel ...

  10. php函数 array_chunk

    array_chunk ( array $array , int $size [, bool $preserve_keys = false ] ) : array 将一个数组分割成多个数组,其中每个数 ...