延迟执行语句处理方式及资源的使用
多个耽误执行语句的处理赏罚次序
当有多个 defer 举动被注册时,它们会以逆序执行(相同栈,即后进先出),下面的代码是将一系列的数值打印语句按次序耽误处理赏罚,如下所示:
package main
import ( "fmt" )
func main() {
fmt.Println("defer begin")
// 将defer放入耽误挪用栈 defer fmt.Println(1)
defer fmt.Println(2)
// 最后一个放入, 位于栈顶, 最先挪用 defer fmt.Println(3)
fmt.Println("defer end") } 代码输出如下:defer begin defer end 3 2 1 功效说明如下:代码的耽误次序与最终的执行次序是反向的。 耽误挪用是在 defer 地址函数竣事时举办,函数竣事可所以正常返回时,也可所以产生宕机时。 行使耽误执行语句在函数退出时开释资源 处理赏罚营业或逻辑中涉及成对的操纵是一件较量啰嗦的工作,好比打开和封锁文件、吸取哀求和回覆哀求、加锁息争锁等。在这些操纵中,最轻易忽略的就是在每个函数退出处正确地开释和封锁资源。 defer 语句正好是在函数退出时执行的语句,以是行使 defer 能很是利便地处理赏罚资源开释题目。 1) 行使耽误并发解锁 在下面的例子中会在函数中并发行使 map,为防备竞态题目,行使 sync.Mutex 举办加锁,拜见下面代码:
var ( // 一个演示用的映射 valueByKey = make(map[string]int) // 担保行使映射时的并发安详的互斥锁 valueByKeyGuard sync.Mutex )
// 按照键读取值 func readValue(key string) int { // 对共享资源加锁 valueByKeyGuard.Lock() // 取值 v := valueByKey[key] // 对共享资源解锁 valueByKeyGuard.Unlock() // 返回值 return v } 代码声名如下:第 3 行,实例化一个 map,键是 string 范例,值为 int。 第 5 行,map 默认不是并发安详的,筹备一个 sync.Mutex 互斥量掩护 map 的会见。 第 9 行,readValue() 函数给定一个键,从 map 中得到值后返回,该函数会在并发情形中行使,必要担保并发安详。 第 11 行,行使互斥量加锁。 第 13 行,从 map 中获取值。 第 15 行,行使互斥量解锁。 第 17 行,返回获取到的 map 值。 行使 defer 语句对上面的语句举办简化,参考下面的代码。
func readValue(key string) int {
valueByKeyGuard.Lock()
// defer后头的语句不会顿时挪用, 而是耽误到函数竣事时挪用 defer valueByKeyGuard.Unlock()
return valueByKey[key] } 上面的代码中第 6~8 行是对前面代码的修改和添加的代码,代码声名如下:第 6 行在互斥量加锁后,行使 defer 语句添加解锁,该语句不会顿时执行,而是等 readValue() 函数返回时才会被执行。 第 8 行,从 map 查询值并返回的进程中,与不行使互斥量的写法一样,比拟上面的代码,这种写法更简朴。 2) 行使耽误开释文件句柄 文件的操纵必要颠末打开文件、获取和操纵文件资源、封锁资源几个进程,假如在操纵完毕后不封锁文件资源,历程将一向无法开释文件资源,在下面的例子中将实现按照文件名获取文件巨细的函数,函数中必要打开文件、获取文件巨细和封锁文件等操纵,因为每一步体系操纵都必要举办错误处理赏罚,而每一步处理赏罚城市造成一次也许的退出,因此就必要在退出时开释资源,而我们必要亲近存眷在函数退出处正确地开释文件资源,参考下面的代码:
// 按照文件名查询其巨细 func fileSize(filename string) int64 {
// 按照文件名打开文件, 返回文件句柄和错误 f, err := os.Open(filename)
// 假如打开时产生错误, 返回文件巨细为0 if err != nil { return 0 }
// 取文件状态信息 info, err := f.Stat()
// 假如获守信息时产生错误, 封锁文件并返回文件巨细为0 if err != nil { f.Close() return 0 }
// 取文件巨细 size := info.Size()
// 封锁文件 f.Close()
// 返回文件巨细 return size } 代码声名如下:第 2 行,界说获取文件巨细的函数,返回值是 64 位的文件巨细值。 第 5 行,行使 os 包提供的函数 Open(),按照给定的文件名打开一个文件,并返回操纵文件用的句柄和操纵错误。 第 8 行,假如打开的进程中产生错误,如文件没找到、文件被占用等,将返回文件巨细为 0。 第 13 行,此时文件句柄 f 可以正常行使,行使 f 的要领 Stat() 来获取文件的信息,获守信息时,也许也会产生错误。 第 16~19 行对错误举办处理赏罚,此时文件是正常打开的,为了开释资源,必必要挪用 f 的 Close() 要领来封锁文件,不然会产生资源泄漏。 第 22 行,获取文件巨细。 第 25 行,封锁文件、开释资源。 第 28 行,返回获取到的文件巨细。 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |