定义函数类型
用type定义
type calculation func(int, int) int
这样就定义好了一个calculation类型函数,后面的函数只要满足它的格式,那就是这个类型;可以和普通类型一样使用; 比如:
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
上面两个函数都可以算calculation类型 我们可以像声明基本类型一样:
var c calculation
c = add
这里c就是add函数,可以像用add函数一样直接用就好了
函数作为参数
因为函数也可以是一种类型,它可以像基本类型那样进行使用
func add(x, y int) int {
return x + y
}
func calc(x, y int, op func(int, int) int) int {
return op(x, y)
}
func main() {
ret2 := calc(10, 20, add)
fmt.Println(ret2) //30
}
匿名函数
立即执行的函数,只调用一次的函数
func main() {
// 将匿名函数保存到变量
add := func(x, y int) {
fmt.Println(x + y)
}
add(10, 20) // 通过变量调用匿名函数
//自执行函数:匿名函数定义完加()直接执行
func(x, y int) {
fmt.Println(x + y)
}(10, 20)
}
闭包
闭包指的是一个函数和与其相关的引用环境组合而成的实体。简单来说,闭包=函数+引用环境。包含了它外部作用域的一个变量
func adder() func(int) int {
var x int
return func(y int) int {
x += y // 包含了它外部作用域的一个变量
return x
}
}
func main() {
var f = adder() // 这是f是adder的返回值func(int)int
fmt.Println(f(10)) //10 把10传进去,执行的是adder return部分
fmt.Println(f(20)) //30
fmt.Println(f(30)) //60
f1 := adder()
fmt.Println(f1(40)) //40
fmt.Println(f1(50)) //90
}
变量f是一个函数并且它引用了其外部作用域中的x变量,此时f就是一个闭包。 在f的生命周期内,变量x也一直有效。
defer语句
defer 后面的语句会被延迟到最后调用,当有好几个先被defer时,defer的语句最后被执行,最后被defer的语句,最先被执行。 例如:
func main() {
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
}
输出就是321
defer执行时机
return语句在底层不是原子操作,它分为给返回值赋值和RET指令两步。而defer语句执行的时机就在返回值赋值操作后,RET指令执行前。具体如下图所示:
图片来自七米老师的博客
这篇文章主要是我自己有一些比较不懂得地方,如要具体学习,可以参考七米老师的博客www.liwenzhou.com/posts/Go/09…