函数签名

函数签名

函数类型又叫函数签名,一个函数的类型就是函数定义首行去掉函数名,参数名和{,可以使用fmt.Printf("%T",func)

package main
import "fmt"
func test(a int) int{
    a++
    return a
}
func main(){
    fmt.Printf("%T",test)
}
//output:
func(int) int

特点

  1. 可以用type来定义函数类型,函数类型可以作为函数的参数或返回值。
  2. 函数可以赋值与变量,可以使函数绑定一个变量,通过变量来调用
func test(a int) int{
    a++
    return a
}
func main(){
    t := test
    println(t(1))
}

匿名函数

顾名思义,没有函数名的函数,可直接赋值给变量,可作为实参,也可作为返回值,亦可直接调用。

package main
var moha = func(hath,hath2 int) int{
    return hath + hath2
}
func refunc() func(int)int{
    return func(a int) int{
        a++
        return a
    }
}
func infunc(f func(int) int) int{
    return f(90,2)
}
func main(){
    println(moha(1,2)) //直接调用
    println(refunc()(1)) //调用返回的函数
    println(infunc(moha)) //传入函数
}

延迟调用

defer

Go中提供defer来提供延迟调用,可以注册多个延迟调用,这些延迟调用遵循FILO(先进后出),顺序在函数返回前被执行。defer常用于保证一些资源最终一定能得到回收和释放,比如文件读写。

package main
func main(){
    defer func(){
        println("three")
    }()
    defer func(){
        println("two")
    }()
println("one")
}

特点

  1. FILO(先进后出)
  2. defer后必须是函数或方法的调用,不能为语句,否则报错:expression in defer must be function call
  3. defer函数的实参在注册时通过值拷贝传递进去,后续的操作语句不会对defer的函数造成影响
package main
func main(){
    a := 1
    defer func(a int){
        println(a)
    }(a) //值拷贝
    a++
    println(a)
}
  1. defer只有注册后才能执行,即在return前有效,在return后因为没有被注册而不会执行
  2. 主动退出(os.Exit(int))defer不会被执行
  3. defer最好不要调用有名函数,否则会产生一些奇奇怪怪的错误
  4. defer一般放在错误检查语句后
  5. 最好不要放在循环里

其他要说的

Go 中 defer 的 5 个坑:https://studygolang.com/articles/12061?fr=sidebar

标签: Golang

添加新评论