这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
函数、闭包,错误处理
-
匿名函数
-
一次性名函数
**fun main(){ //定义即调用 func(n1 int,n2 int)int{ return n1 + n2 }(10,20) //此时在定义的时候同时调用 }** -
全局匿名函数
**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) }** -
多次匿名函数(变量调用的匿名函数)
**var( Fun1 = func(n1 int,n2 int)int{ return n1 * n2 } ) //定义全局匿名函数首字母'F'要大写,但是小写也没有报错哎 //调用 func main(){ a := Fun1(10,100) fmt.Println("a=",a) }**
-
-
闭包
一个函数与相关的引用环境组成的一个整体(实体)
-
闭包的解决:
- 可以让一个变量常驻内存
- 可以让一个变量不污染全局
-
写法
函数里面嵌套一个函数,最后返回里面的函数。
**//作用是返回一个函数,这个函数可以累加,每次累加的值是上次累加的值加上本次传入的值 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 } }** -
闭包的理解:把闭包作为一个类class,字段i是一个属性,函数是方法,那么i和函数构成闭包
关键:返回的函数引用到哪些变量,就是函数与哪些变量构成闭包
**func getSequence() func() int { //getSequence()是一个函数,返回的数据类型是func()int i:=0 //func()是一个匿名函数 return func() int { i+=1 return i }** -
注意参数的规范性:
我们为了规范性,建议不使用参数的定义
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 } }** -
闭包的升级版
-
值传递&引用传递
-
adder()与adder()()一个是返回的闭包函数,另一个是对闭包函数的调用
-
闭包的延迟绑定:闭包的神奇之处,它会保存相关引用的环境,也就是说,
**val这个变量在闭包内的生命周期得到了保证。因此在执行这个闭包的时候,会去外部环境寻找最新的数值** -
goRuntinue的延迟绑定
-
-
-
字符串常用系统函数
**// 关于string的常用函数
-
len(str) 内建函数,返回字符串长度,按字节,1个汉字3字节,1字母1字节 这个函数是内建函数(和printf一样) //只需要
fmt包 -
range []rune(str) 字符串遍历,处理中文问题 转成rune切片
-
string转整数 strconv.Atoi(str) 这个函数是 strconv.ParseInt(s string, base int, bitSize int) (i int64 err error)的简化版
-
整数转string strconv.Itoa(666) 是strconv.FormatInt(i int64, base int) string的简化版
-
十进制数转2 8 16进制字符串 strconv.FormatInt(i int64, base int) string base->2,8,16
-
判断字符串s是否包含子串substr strings.Contains(s, substr string) bool
-
统计子串出现次数 strings.Count(s, sep string) int
-
判断2个字符串是否相等 str1 == str2 区分大小写, 不区分大小写方式strings.EqualFold(s, t string) bool
-
子串sep在字符串s中第一次/最后一次出现的位置,不存在则返回-1 Index(s, sep string) int/LastIndex(s, sep string) int
-
将n个old子串替换为new字符串,n<0会替换所有old子串 strings.Replace(s, old, new string, n int) string
-
大小写转换 strings.ToUpper /ToLower
-
按sep拆分字符串,返回一个slice strings.Split(s, sep string) []string
-
将字符串slice以sep为分隔符组合成一个字符串 strings.Join(a []string, sep string) string
-
Trim系列 Trim(s string, cutset string) string 去除左右两边指定字符串 TrimRight/TrimLeft TrimSpace(s string) string 去除左右两边空白 TrimPrefix(s, prefix string) string /TrimSuffix(s, suffix string) string 去除前/后缀
-
判断s是否有前缀/后缀字符串prefix HasPrefix(s, prefix string) bool / HasSuffix**
-
-
时间相关函数
-
引入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() int64Unix 返回 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)**
-
-
错误处理机制
panic,defer,recover-
Go中可以抛出一个
panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理 -
使用
defer和recover来处理异常。 -
注意:
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 }
-