Go语言学习——函数二 defer语句
函数
package main
import "fmt"
// 函数:一段代码的封装
func f1(){
fmt.Println("Hello 中国!")
}
func f2(name string) {
fmt.Println("Hello", name)
}
// 带参数和返回值的函数
func f3(x int, y int) int {
sum := x + y
return sum
}
// 参数类型简写
func f4(x, y int) int {
return x + y
}
// 可变参数
func f5(title string, y ...int) int {
fmt.Println(y) // y是一个int类型的切片
return 1
}
// 命名返回值
func f6(x, y int) (sum int) {
sum = x + y // 如果使用命名的返回值,那么在函数中可以直接使用返回值变量
return // 如果使用命名的返回值 return 后面可以省略返回值变量
}
// Go语言中支持多个返回值
func f7(x, y int) (sum, sub int) {
sum = x + y
sub = x - y
return
}
func main () {
f1()
f2("理想")
f2("梦想")
f3(100, 200) // 调用函数
fmt.Println(f3(100, 200))
ret := f3(300, 400)
fmt.Println(ret)
f5("太阳", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 在一个命名的函数中不能够再声明命名函数
// func f8() {
// }
}
defer语句
defer语句会将其后面跟随的语句进行延迟处理
在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行
先被defer的语句最后被执行,最后被defer的语句,最先被执行
package main
import "fmt"
// defer
// defer多用于函数结束之前释放资源(文件句柄、数据库连接、socket连接)
func deferDemo(){
fmt.Println("start")
defer fmt.Println("hello") // defer把它后面的语句延迟到函数即将返回的时候再执行
defer fmt.Println("apple") // 一个函数中可以有多个defer语句
defer fmt.Println("banana") // 多个defer语句安装先进后出(后进先出)的顺序延迟执行
fmt.Println("end")
}
func main(){
deferDemo()
}
defer执行时机
return语句在底层并不是原子操作,它分为给返回值赋值和RET指令两步
defer语句执行的时机在返回值赋值操作后,RET指令执行前
package main
import "fmt"
// Go语言中函数的return不是原子操作,在底层分为两步来执行
// 第一步:返回值赋值
// defer
// 第二版:真正的RET返回
// 函数中如果存在defer,那么defer执行的时机是在第一步和第二步之间
func f1() int {
x := 5
defer func() {
x++ // 修改的是x不是返回值
}()
return x
}
func f2() (x int) {
defer func() {
x++
}()
return 5 // 返回值=x
}
func f3() (y int) {
x := 5
defer func() {
x++ // 修改的是x
}()
return x // 返回值=y=x=5
}
func f4() (x int) {
defer func(x int) {
x++ // 改变的是函数中的副本
}(x)
return 5 // 返回值=x=5
}
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
fmt.Println(f4())
}
本文来自博客园,作者:寻月隐君,转载请注明原文链接:https://www.cnblogs.com/QiaoPengjun/p/16244411.html