Bruce Blog Bruce Blog
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航

Bruce Tao

运维界的该溜子
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航
  • 基础

    • Golang环境

    • 语法

    • 数据类型与运算符

    • 分支语句

    • 循环语句

    • 数组

    • 切片

    • Map

    • String

    • 函数

      • 函数
      • 函数的使用
      • 函数的参数
      • 函数的返回值
      • return语句
      • 函数中变量作用域
      • 递归函数
      • defer语句
        • 函数的数据类型
        • 函数的本质
        • 匿名函数
        • 回调函数
        • 闭包
      • 包的管理

      • 指针

      • 结构体

      • Go语言中的OOP

      • 方法和接口

      • 错误处理

    • Go进阶

    • Go框架

    • Golang辅助

    • Golang
    • 基础
    • 函数
    Bruce
    2022-10-27
    目录

    defer语句

    # defer

    # 1.1 延迟是什么?

    • 即延迟(defer)语句,延迟语句被用于执行一个函数调用,在这个函数之前,延迟语句返回.

    # 1.2 延迟函数

    • 可以在函数中添加多个defer语句.当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回.特别是当在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前需要关闭相应的资源,不然很容易造成资源泄露等问题
    • 如果有很多调用defer,那么defer是采用后进先出模式
    • 在离开所在的方法时,执行(报错的时候也会执行)
    func ReadWrite() bool {
        file.Open("file")
        defer file.Close()
        if failureX {
              return false
        } if failureY {
              return false
        } 
        return true
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    最后才执行file.Close()

    示例代码:

    package main
    
    import "fmt"
    
    func main() {
    	a := 1
    	b := 2
    	defer fmt.Println(b)
    	fmt.Println(a)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    运行结果:

    1
    2
    
    1
    2

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func finished() {  
        fmt.Println("Finished finding largest")
    }
    
    func largest(nums []int) {  
        defer finished()    
        fmt.Println("Started finding largest")
        max := nums[0]
        for _, v := range nums {
            if v > max {
                max = v
            }
        }
        fmt.Println("Largest number in", nums, "is", max)
    }
    
    func main() {  
        nums := []int{78, 109, 2, 563, 300}
        largest(nums)
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    运行结果:

    Started finding largest  
    Largest number in [78 109 2 563 300] is 563  
    Finished finding largest 
    
    1
    2
    3

    # 1.3 延迟方法

    • 延迟并不仅仅局限于函数.延迟一个方法调用也是完全合法的.

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    
    type person struct {  
        firstName string
        lastName string
    }
    
    func (p person) fullName() {  
        fmt.Printf("%s %s",p.firstName,p.lastName)
    }
    
    func main() {  
        p := person {
            firstName: "John",
            lastName: "Smith",
        }
        defer p.fullName()
        fmt.Printf("Welcome ")  
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    运行结果:

    Welcome John Smith 
    
    1

    # 1.4 延迟参数

    • 延迟函数的参数在执行延迟语句时被执行,而不是在执行实际的函数调用时执行.

    示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func printA(a int) {  
        fmt.Println("value of a in deferred function", a)
    }
    func main() {  
        a := 5
        defer printA(a)
        a = 10
        fmt.Println("value of a before deferred function call", a)
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    运行结果:

    value of a before deferred function call 10  
    value of a in deferred function 5 
    
    1
    2

    # 1.5 堆栈的推迟

    • 当一个函数有多个延迟调用时,它们被添加到一个堆栈中,并在Last In First Out(LIFO)后进先出的顺序中执行.

    编写一个小程序,它使用一堆defers打印一个字符串.示例代码:

    package main
    
    import (  
        "fmt"
    )
    
    func main() {  
        name := "Naveen"
        fmt.Printf("Orignal String: %s\n", string(name))
        fmt.Printf("Reversed String: ")
        for _, v := range []rune(name) {
            defer fmt.Printf("%c", v)
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    运行结果:

    Orignal String: Naveen  
    Reversed String: neevaN 
    
    1
    2

    # 1.6defer注意点

    # defer函数
    • 当外围函数中的语句正常执行完毕时,只有其中所有的延迟函数都执行完毕,外围函数才会真正的结束执行.
    • 当执行外围函数中的return语句时,只有其中所有的延迟函数都执行完毕后,外围函数才会真正返回.
    • 当外围函数中的代码引发运行恐慌时,只有其中所有的延迟函数都执行完毕后,该运行时恐慌才会真正被扩展至调用函数.
    上次更新: 2024/04/09, 16:48:42
    递归函数
    函数的数据类型

    ← 递归函数 函数的数据类型→

    最近更新
    01
    AWS NAT-NetWork-Firwalld配置(一)
    04-09
    02
    AWS NAT-NetWork-Firwalld配置(二)
    04-09
    03
    kubernetes部署minio对象存储
    01-18
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Bruce Tao Blog Space | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式