Go语言入门四 | 青训营笔记

52 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

函数、闭包,错误处理

  1. 匿名函数

    1. 一次性名函数

      **fun main(){
      	//定义即调用
          func(n1 int,n2 int)int{
              return n1 + n2
          }(10,20)
      	//此时在定义的时候同时调用
      }**
      
    2. 全局匿名函数

      **fun main(){
          a := func(n1 int,n2 int)int{
              return n1 - n2
          }
      	//使用变量调用
          res := a(30,20)
          fmt.Println("res="res)
          res2 := a(30,40)
          fmt.Println("res3=",res3)
      }**
      
    3. 多次匿名函数(变量调用的匿名函数)

      **var(
      	Fun1 = func(n1 int,n2 int)int{
      		return n1 * n2
      		}
      )          //定义全局匿名函数首字母'F'要大写,但是小写也没有报错哎
      
      //调用
      func main(){
          a := Fun1(10,100)
          fmt.Println("a=",a)
      }**
      
  2. 闭包

    一个函数与相关的引用环境组成的一个整体(实体)

    1. 闭包的解决:

      • 可以让一个变量常驻内存
      • 可以让一个变量不污染全局
    2. 写法

      函数里面嵌套一个函数,最后返回里面的函数。

      **//作用是返回一个函数,这个函数可以累加,每次累加的值是上次累加的值加上本次传入的值
      func adder() func(int) int {
      	//1.func(int) int 代表这个函数接收一个int类型的参数,返回一个int类型的值
      	var x int = 10
      	return func(y int) int {
      		x += y
      		return x
      	}
      }
      
      //可以是10常驻内存且不污染全局
      func adder2() func() int {
      //2.func() int 代表这个函数返回一个int类型的值
      	var x int = 10
      	return func() int {
      		return x
      	}
      }**
      
    3. 闭包的理解:把闭包作为一个类class,字段i是一个属性,函数是方法,那么i和函数构成闭包

      关键:返回的函数引用到哪些变量,就是函数与哪些变量构成闭包

      **func getSequence() func() int {   //getSequence()是一个函数,返回的数据类型是func()int
      	i:=0               //func()是一个匿名函数
        return func() int {
        i+=1
        return i
       }**
      
    4. 注意参数的规范性:

      我们为了规范性,建议不使用参数的定义

      func(y int) int ➡️ func(int) int

      **func adder() func(int) int {
      	//func(int) int 代表这个函数接收一个int类型的参数,返回一个int类型的值
      	var x int = 10
      	return func(y int) int {
      		x += y
      		return x
      	}
      }**
      
    5. 闭包的升级版

      1. 值传递&引用传递

      2. adder()adder()()

        一个是返回的闭包函数,另一个是对闭包函数的调用

      3. 闭包的延迟绑定:闭包的神奇之处,它会保存相关引用的环境,也就是说,**val这个变量在闭包内的生命周期得到了保证。因此在执行这个闭包的时候,会去外部环境寻找最新的数值**

      4. goRuntinue的延迟绑定

  3. 字符串常用系统函数

    **// 关于string的常用函数

    1. len(str) 内建函数,返回字符串长度,按字节,1个汉字3字节,1字母1字节 这个函数是内建函数(和printf一样) //只需要fmt

    2. range []rune(str) 字符串遍历,处理中文问题 转成rune切片

    3. string转整数 strconv.Atoi(str) 这个函数是 strconv.ParseInt(s string, base int, bitSize int) (i int64 err error)的简化版

    4. 整数转string strconv.Itoa(666) 是strconv.FormatInt(i int64, base int) string的简化版

    5. 十进制数转2 8 16进制字符串 strconv.FormatInt(i int64, base int) string base->2,8,16

    6. 判断字符串s是否包含子串substr strings.Contains(s, substr string) bool

    7. 统计子串出现次数 strings.Count(s, sep string) int

    8. 判断2个字符串是否相等 str1 == str2 区分大小写, 不区分大小写方式strings.EqualFold(s, t string) bool

    9. 子串sep在字符串s中第一次/最后一次出现的位置,不存在则返回-1 Index(s, sep string) int/LastIndex(s, sep string) int

    10. 将n个old子串替换为new字符串,n<0会替换所有old子串 strings.Replace(s, old, new string, n int) string

    11. 大小写转换 strings.ToUpper /ToLower

    12. 按sep拆分字符串,返回一个slice strings.Split(s, sep string) []string

    13. 将字符串slice以sep为分隔符组合成一个字符串 strings.Join(a []string, sep string) string

    14. Trim系列 Trim(s string, cutset string) string 去除左右两边指定字符串 TrimRight/TrimLeft TrimSpace(s string) string 去除左右两边空白 TrimPrefix(s, prefix string) string /TrimSuffix(s, suffix string) string 去除前/后缀

    15. 判断s是否有前缀/后缀字符串prefix HasPrefix(s, prefix string) bool / HasSuffix**

  4. 时间相关函数

    • 引入time包,time.Time 类型,用于表示时间

      fmt.Println(now.Year()) //获取到年 fmt.Println(int(now.Month())) //获取到月 fmt.Println(now.Day()) //获取到日 fmt.Println(now.Hour()) //获取到时 fmt.Println(now.Minute()) //获取到分 fmt.Println(now.Second()) //获取到秒

    • 时间常量

      Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond Millisecond = 1000 * Microsecond Second = 1000 * Millisecond Minute = 60 * Second Hour = 60 * Minute**

    • sleep

      **for{
         i++
         fmt.Println(i)  //打印
         time.Sleep(time.Second)   //休眠,每秒钟执行一次
         if i == 10{
             break
         }
      }**
      
    • 统计代码运行时间:时间戳

      • func (Time) Unix
      func (t Time) Unix() int64
      

      Unix 返回 t 作为 Unix 时间,即自 1970 年 1 月 1 日 UTC 以来经过的秒数。结果不依赖于与 t 关联的位置。类 Unix 操作系统通常将时间记录为 32 位的秒数,但由于此处的方法返回 64 位值,因此它在过去或未来数十亿年内有效。

      **start := time.Now().Unix()
      test()
      end := time.Now().Unix()
      fmt.Println("执行test消耗的时间为(s):",end - start)**
      
  5. 错误处理机制

    panic,defer,recover

    • Go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理

    • 使用deferrecover来处理异常。

    • 注意:recover只有在defer调用的函数中有效

    • 顺序:正常执行1→遇到panic2→执行延迟执行的内容defer3→执行panic4

    **func fn2() {
    	defer func() {//3
    		if err := recover(); err != nil {
    			fmt.Println("有错误 err", err)
    		}
    	}()
    	panic("fn2")//2,4
    }**
    
    • 自定义错误
      func readConf(name string) (err error) {
          if name == "config.ini" {
                  //"读取"
                  return nil
          } else {
                  //返回一个自定义错误
                  return errors.New("读取文件错误")
          }
          fmt.Println(name)
          return
          }