1 函数
- Go 函数 不支持 嵌套、重载和默认参数
- 无需声明原型、不定长度变参、多返回值、命名返回值参数
匿名函数、闭包
- 定义函数使用关键字 func,且左大括号不能另起一行
- 函数也可以作为一种类型使
package main
import "fmt"
func main() {
s1 := []int{1, 2, 3,4}
A(s1)
fmt.Println(s1)
}
func A(s []int) {
s[0] = 5
s[1] = 6
s[2]=7
s[3]=8
fmt.Println(s)
}
package main
import "fmt"
func main() {
a := 1
A(&a)
fmt.Println(a)
}
//并不是传递一个指针,而是对slice的内存地址进行拷贝
func A(a *int) {
*a = 2
fmt.Println(*a)
}
2 函数也是一种数据类型
package main
import "fmt"
func main() {
a := A
a()
}
func A() {
fmt.Println("A 函数")
}
package main
import "fmt"
func main() {
f:=closure(10)
fmt.Println(f(1))
fmt.Println(f(2))
}
func closure(x int) func(int) int {
fmt.Printf("%p\n",&x)
return func(y int) int {
fmt.Printf("%p\n",&x)
return x + y
}
}
3 defer
- 执行方式类似其它语言中的析构函数,在函数体执行结束后
按照调用顺序的相反顺序逐个执行
- 即使函数发生严重错误也会执行
- 支持匿名函数的调用
- 常用于资源清理、文件关闭、解锁以及记录时间等操作
- 通过与匿名函数配合可在return之后修改函数计算结果
- 如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer
时即已经获得了拷贝,否则则是引用某个变量的地址
- Go 没有异常机制,但有 panic/recover 模式来处理错误
- Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效
func main() {
for i:=0;i<5;i++{
defer fmt.Println(i)
}
}
func main() {
for i:=0;i<3;i++{
defer func(){
fmt.Println(i)
}()
}
}
package main
import "fmt"
func main() {
A()
B()
C()
}
func A(){
fmt.Println("Func A")
}
func B(){
panic("panic in B")
}
func C(){
fmt.Println("Func C")
}
package main
import "fmt"
func main() {
A()
B()
C()
}
func A() {
fmt.Println("Func A")
}
func B() {
defer func() {
if err := recover(); err != nil {
fmt.Println("Recover in B")
}
}()
panic("panic in B")
}
func C() {
fmt.Println("Func C")
}
4 思考题
func main() {
var fs=[4]func(){}
for i:=0;i<4;i++{
defer fmt.Println("defer i=",i)
defer func(){
fmt.Println("defer_closure i= ",i)
}()
fs[i]=func(){
fmt.Println("closure i = ",i)
}
}
for _,f:=range fs{
f()
}
}