马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1. 跳出/执行下一次循环。
- {标签名}:
- for true {
- ...
- for true {
- ...
- break/continue {标签名} //默认不加标签,则跳出最近一层循环。加了标签可以跳出标签定义处所在循环
- }
- }
复制代码 2. map的使用注意项。
因为map是指针,作为参数传递时,在函数内部对map作的修改直接修改外部传递变量的值。
3. slice(切片)使用注意点。
与map一样,都可以用make创建,但slice返回的是结构体。当slice作为参数传递时,在函数内部修改可能会影响slice
4. 遍历循环for range和排序sort的使用。
- package main
- import (
- "fmt"
- "sort"
- )
- func main() {
- sl := []int{219, 373, 543, 351, 523, 625, 436, 252, 121, 567, 896, 454, 342, 734, 464, 423, 164}
- min, max := getMinAndMax(sl)
- fmt.Println("sl中最小值:", min)
- fmt.Println("sl中最大值:", max)
- sort.Ints(sl) //根据类型进行正向排序
- fmt.Println("切片排序获取sl中最小值:", sl[0])
- fmt.Println("切片排序获取sl中最大值_1:", sl[len(sl)-1:][0])
- sort.Sort(sort.Reverse(sort.IntSlice(sl))) //反射排序
- fmt.Println("切片排序获取sl中最大值_2:", sl[0])
- }
- func getMinAndMax(arr []int) (min int, max int) {
- if len(arr) == 0 {
- return
- }
- min, max = arr[0], arr[0]
- for _, v := range arr {
- if v > max {
- max = v
- } else if v < min {
- min = v
- }
- }
- return
- }
复制代码 上面代码执行结果:- sl中最小值: 121
- sl中最大值: 896
- 切片排序获取sl中最小值: 121
- 切片排序获取sl中最大值_1: 896
- 切片排序获取sl中最大值_2: 896
复制代码 5. defer用法。
- defer是函数退出前必须执行逻辑,类似栈,后进先出,最后执行要先写
复制代码- package main
- import (
- "fmt"
- )
- func main() {
- fmt.Println("start...")
- for i := 0; i < 3; i++ {
- defer fmt.Println(i)
- }
- fmt.Println("end")
- }
复制代码 上面代码执行结果:defer函数实参是值拷贝进去,所以i++不影响defer中的值。
注意:return之后的defer不会执行;调用os.Exit(1)的函数不执行defer。- package main
- import (
- "fmt"
- )
- //return后写defer
- func main() {
- fmt.Println("start...")
- return
- defer fmt.Println("defer逻辑")
- fmt.Println("end")
- }
- //函数中使用了os.Exit(1)
- func main() {
- fmt.Println("start...")
- defer fmt.Println("defer逻辑")
- fmt.Println("end")
- os.Exit(1)
- }
复制代码 6. 匿名函数用法。
- package main
- import (
- "fmt"
- "time"
- )
- var FunB = func() {
- fmt.Println("全局匿名函数")
- }
- func main() {
- fmt.Println("start...")
- go func() {
- fmt.Println("匿名函数")
- }()
- a := func() {
- fmt.Println("给变量赋值的匿名函数")
- }
- go a()
- go FunB()
- time.Sleep(1 * time.Second)
- fmt.Println("end")
- }
复制代码 7. defer + recover捕获panic,不会让一个panic使整个app程序奔溃的简单方法,提高程序的健壮性。
- package main
- import "fmt"
- func main() {
- testPanic()
- fmt.Println("test_end")
- }
- func testPanic() {
- defer func() {
- err := recover()
- if err != nil {
- fmt.Println("panic被捕获")
- }
- }()
- a := 10
- b := 0
- fmt.Println("a/b=", a/b)
- }
复制代码 8. 自定义错误。
9. 自定义函数进行多函数单一操作。
- package main
- import "fmt"
- func add(a, b int) int {
- return a + b
- }
- func sub(a, b int) int {
- return a - b
- }
- func nul(a, b int) int {
- return a * b
- }
- type Op func(int, int) int
- func do(f Op, a, b int) int {
- return f(a, b)
- }
- func main() {
- c, d := 102087, 65421
- e := do(add, c, d)
- fmt.Println("c+d=", e)
- f := do(sub, c, d)
- fmt.Println("c-d=", f)
- g := do(nul, c, d)
- fmt.Println("c*d=", g)
- }
复制代码 10. 接口的使用说明。
接口是一种抽象类型,接口实现时要注意值与指针接收者的问题。
在go语言中,一个类型(主要是struct)可以实现多个不同的接口,接口之间互不影响;也可以多个类型实现同一个接口,即间接实现面向对象的开发方式。go里面的接口不需要类型(对象)完全实现所有函数方法,接口可以通过在类型中嵌入其它类型来实现。还可以通过接口不断嵌套创造出新的接口。
注意:go语言中有空接口概念(interface{}),即没有定义任何函数方法的接口,因此任何类型都实现了空接口,空接口类型的变量也就可以接收任意类型的变量(类似其它面向对象语言中的Object对象),用途非常广但需要断言正确,否则实现出现未知错误。
11. goroutine 并发使用。
并发是指同一时间段内执行的多个任务。并行是指同一时刻执行多个任务。goroutine是go语言中并发的实现,它类似于线程,但是属于用户态的线程,由go语言运行时调度完成,不同于线程由操作系统调度完成。- ...
- go func(){
- //并发执行函数逻辑
- }()
- ...
复制代码 常用sync.Wait.WaitGroup来解决多个并发中安全问题
12. 多个并发goroutine之前的通信channel应用。
chan类型也和map、slice(切片)类型一样,用make创建。
-end-
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |