前言
本专栏是笔者在学习《Go程序设计语言》这本书时,对每个章节认为较为重要(容易忘记👻)的知识点记录的笔记,其中也会有少量的思考👀, 现整理成博客分享出来。
如果对专栏感兴趣,跑过去看一眼,书中的每一章都有:《Go程序设计语言》笔记
❗️注意❗️:本专栏不是详细的知识讲解,只是碎片的知识条目,或可作为Go知识点查漏补缺的小工具~
函数声明
- 每个函数都包含:名字,形参列表,返回列表,函数体;
func name(para-list) (return-list){}
; - 如果几个形参或者返回值类型相同,那么类型只需要写一次;
func name(x, y, z int)(a, b int){}
Go
语言没有默认参数;不支持重载函数;- 实参是按值传递的,函数接收到的是每个实参的副本;除非实参是引用类型:
slice, map, func, chan, pointer
;
递归
- 函数可以递归调用;
Go
的函数调用栈是可变长度的,可达到1GB
左右的上限;
多返回值
Go
语言的垃圾回收机制将回收未使用的内存,但不能指望它会释放未使用的操作系统资源,比如打开的文件、网络连接等;所以必须显式地关闭resp.Body
;- 一个函数如果有命名的返回值,则可以省略
return
语句的操作数,称为裸返回;但应保守使用;
错误
error
是内置的接口类型;当一个函数返回错误时,也可能返回部分有用的结果,所以好好看文档,如果存在部分有用结果,在错误处理前,先处理这些不完整的返回结果;Go
使用普通值而非异常来报告错误,异常只是针对程序bug
导致的预料外的错误,而不能作为常规的错误处理方法出现在程序中;fmt.Errorf
格式化并返回一个错误;在设计中可以将错误链串联起来,方便错误的定位;- 文件读取时,总会碰到文件结束,此时产生一个
io.EOF
错误;
函数变量
%*s
中的*
用于输出带有可变数量空格的字符串;
匿名函数
- 命名函数只能在包级别的作用域进行声明;匿名函数可以在任何表达式内指定函数变量;
- 匿名函数声明:
func(para-list)(return-list){}
; - 里层函数可以使用到外层函数中的变量;通常把函数变量称为闭包;
- 捕获迭代变量的词法陷阱:如
for
作用域的迭代变量i
,它在整个for
循环中有效,如果将每个i
存起来,在循环外再调用i
,最终的i
是同一个值;可以在块中声明一个ii := i
,这样每次迭代都存储的新变量ii
;- 但如果是将其复制一份则没关系,如将其
append
到一个slice
中;
- 但如果是将其复制一份则没关系,如将其
变长函数
- 形参数量可变的函数,如
fmt.Println()
; - 设置形参如
vals ...int
,函数体中vals
将是一个[]int
,传参可以:1,2,3,4
或是arr...
,其中arr
是一个[]int
; args ...interface{}
可以接收任意类型的参数;
延迟函数调用
defer funcName();
延迟调用函数,参数和表达式会在执行语句时求值,实际调用推迟到包含defer语句的函数结束后才执行;defer
语句没有次数限制,执行时按照调用顺序的倒序执行;- 在复杂的控制流中,随时可能
return
,可以在进入控制流之前使用defer
将资源释放; - 十分好用的场景:
http
的HandleFunc
中,使用defer resp.Body.Close()
;
宕机
- 运行时错误(如数据越界、引用空指针等)导致宕机;
- 宕机时,
goroutine
中所有延迟函数会执行,然后程序异常退出并留下一条日志消息;日志消息中,每一个goroutine
都会显示一个函数调用的栈跟踪消息; - 主动调用宕机函数:
panic
;但尽量用error
预期的错误; - 宕机时,延迟函数会在宕机之后、栈清理之前执行;
恢复
- 宕机时可以退出程序,也可以恢复程序,使用内置的
recover
函数; recorver
函数在延迟函数内部调用、且发生宕机时,会终止当前宕机状态并返回宕机的值;其它时候调用recover
函数则无任何效果且返回nil
;recover
应当慎用;- 也有无法
recover
的情况:内存耗尽使得发生严重你错误而直接终止进程时;
如有错误 ❌ ,欢迎指正 ☝️~
如有收获 🍗,可以考虑点赞👍/评论💬/收藏⭐️/关注👀,大家共同进步~