Go语言学习总结

半亩花草  论坛元老 | 2023-6-17 20:00:09 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1865|帖子 1865|积分 5595

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 跳出/执行下一次循环。
  1. {标签名}:
  2. for true {
  3.    ...
  4.    for true {
  5.        ...
  6.        break/continue {标签名}  //默认不加标签,则跳出最近一层循环。加了标签可以跳出标签定义处所在循环
  7.    }
  8. }
复制代码
2. map的使用注意项。

因为map是指针,作为参数传递时,在函数内部对map作的修改直接修改外部传递变量的值。
3. slice(切片)使用注意点。

与map一样,都可以用make创建,但slice返回的是结构体。当slice作为参数传递时,在函数内部修改可能会影响slice
4. 遍历循环for range和排序sort的使用。
  1. package main
  2. import (
  3.         "fmt"
  4.         "sort"
  5. )
  6. func main() {
  7.         sl := []int{219, 373, 543, 351, 523, 625, 436, 252, 121, 567, 896, 454, 342, 734, 464, 423, 164}
  8.         min, max := getMinAndMax(sl)
  9.         fmt.Println("sl中最小值:", min)
  10.         fmt.Println("sl中最大值:", max)
  11.         sort.Ints(sl) //根据类型进行正向排序
  12.         fmt.Println("切片排序获取sl中最小值:", sl[0])
  13.         fmt.Println("切片排序获取sl中最大值_1:", sl[len(sl)-1:][0])
  14.         sort.Sort(sort.Reverse(sort.IntSlice(sl))) //反射排序
  15.         fmt.Println("切片排序获取sl中最大值_2:", sl[0])
  16. }
  17. func getMinAndMax(arr []int) (min int, max int) {
  18.         if len(arr) == 0 {
  19.                 return
  20.         }
  21.         min, max = arr[0], arr[0]
  22.         for _, v := range arr {
  23.                 if v > max {
  24.                         max = v
  25.                 } else if v < min {
  26.                         min = v
  27.                 }
  28.         }
  29.         return
  30. }
复制代码
上面代码执行结果:
  1. sl中最小值: 121
  2. sl中最大值: 896
  3. 切片排序获取sl中最小值: 121
  4. 切片排序获取sl中最大值_1: 896
  5. 切片排序获取sl中最大值_2: 896
复制代码
5. defer用法。
  1. defer是函数退出前必须执行逻辑,类似栈,后进先出,最后执行要先写
复制代码
  1. package main
  2. import (
  3.         "fmt"
  4. )
  5. func main() {
  6.         fmt.Println("start...")
  7.         for i := 0; i < 3; i++ {
  8.                 defer fmt.Println(i)
  9.         }
  10.         fmt.Println("end")
  11. }
复制代码
上面代码执行结果:
  1. start...
  2. end
  3. 2  
  4. 1  
  5. 0  
复制代码
defer函数实参是值拷贝进去,所以i++不影响defer中的值。
注意:return之后的defer不会执行;调用os.Exit(1)的函数不执行defer。
  1. package main
  2. import (
  3.         "fmt"
  4. )
  5. //return后写defer
  6. func main() {
  7.         fmt.Println("start...")
  8.         return
  9.         defer fmt.Println("defer逻辑")
  10.         fmt.Println("end")
  11. }
  12. //函数中使用了os.Exit(1)
  13. func main() {
  14.         fmt.Println("start...")
  15.         defer fmt.Println("defer逻辑")
  16.         fmt.Println("end")
  17.         os.Exit(1)
  18. }
复制代码
6. 匿名函数用法。
  1. package main
  2. import (
  3.         "fmt"
  4.         "time"
  5. )
  6. var FunB = func() {
  7.         fmt.Println("全局匿名函数")
  8. }
  9. func main() {
  10.         fmt.Println("start...")
  11.         go func() {
  12.                 fmt.Println("匿名函数")
  13.         }()
  14.         a := func() {
  15.                 fmt.Println("给变量赋值的匿名函数")
  16.         }
  17.         go a()
  18.         go FunB()
  19.         time.Sleep(1 * time.Second)
  20.         fmt.Println("end")
  21. }
复制代码
7. defer + recover捕获panic,不会让一个panic使整个app程序奔溃的简单方法,提高程序的健壮性。
  1. package main
  2. import "fmt"
  3. func main() {
  4.         testPanic()
  5.         fmt.Println("test_end")
  6. }
  7. func testPanic() {
  8.         defer func() {
  9.                 err := recover()
  10.                 if err != nil {
  11.                         fmt.Println("panic被捕获")
  12.                 }
  13.         }()
  14.         a := 10
  15.         b := 0
  16.         fmt.Println("a/b=", a/b)
  17. }
复制代码
8. 自定义错误。
  1. errors.New("自定义错误内容")
复制代码
9. 自定义函数进行多函数单一操作。
  1. package main
  2. import "fmt"
  3. func add(a, b int) int {
  4.         return a + b
  5. }
  6. func sub(a, b int) int {
  7.         return a - b
  8. }
  9. func nul(a, b int) int {
  10.         return a * b
  11. }
  12. type Op func(int, int) int
  13. func do(f Op, a, b int) int {
  14.         return f(a, b)
  15. }
  16. func main() {
  17.         c, d := 102087, 65421
  18.         e := do(add, c, d)
  19.         fmt.Println("c+d=", e)
  20.         f := do(sub, c, d)
  21.         fmt.Println("c-d=", f)
  22.         g := do(nul, c, d)
  23.         fmt.Println("c*d=", g)
  24. }
复制代码
10. 接口的使用说明。

接口是一种抽象类型,接口实现时要注意值与指针接收者的问题。
在go语言中,一个类型(主要是struct)可以实现多个不同的接口,接口之间互不影响;也可以多个类型实现同一个接口,即间接实现面向对象的开发方式。go里面的接口不需要类型(对象)完全实现所有函数方法,接口可以通过在类型中嵌入其它类型来实现。还可以通过接口不断嵌套创造出新的接口。
注意:go语言中有空接口概念(interface{}),即没有定义任何函数方法的接口,因此任何类型都实现了空接口,空接口类型的变量也就可以接收任意类型的变量(类似其它面向对象语言中的Object对象),用途非常广但需要断言正确,否则实现出现未知错误。
11. goroutine 并发使用。

并发是指同一时间段内执行的多个任务。并行是指同一时刻执行多个任务。goroutine是go语言中并发的实现,它类似于线程,但是属于用户态的线程,由go语言运行时调度完成,不同于线程由操作系统调度完成。
  1. ...
  2.         go func(){
  3.            //并发执行函数逻辑
  4.         }()
  5. ...
复制代码
常用sync.Wait.WaitGroup来解决多个并发中安全问题
12. 多个并发goroutine之前的通信channel应用。

chan类型也和map、slice(切片)类型一样,用make创建。
-end-

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表