// GO 语言defer(延迟执行语句) // Go 语言的 defer 语句会将其后面跟随的语句进行延迟处理。 // 在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行, // 也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。
package main import( "fmt"
"sync"
"os"
"strconv" ) func PrintStr(str string){ fmt.Println(str) } func testDeferOrder(){ PrintStr("函数开始执行") str := "延迟调用函数" defer PrintStr(str + "1") defer PrintStr(str + "2") defer PrintStr(str + "3") PrintStr("函数结束执行") } var ( // 一个演示用的映射
valueByKey = make(map[string]int) // 保证使用映射时的并发安全的互斥锁
valueByKeyGuard sync.Mutex ) func readValue(key string) int { valueByKeyGuard.Lock() // defer后面的语句不会马上调用, 而是延迟到函数结束时调用
defer valueByKeyGuard.Unlock() return valueByKey[key] } func fileSize(filename string) int64 { f, err := os.Open(filename) if err != nil { return 0 } // 延迟调用Close, 此时Close不会被调用
defer f.Close() info, err := f.Stat() if err != nil { // defer机制触发, 调用Close关闭文件
return 0 } size := info.Size() // defer机制触发, 调用Close关闭文件
return size } func main(){ // 测试执行顺序
testDeferOrder(); // 使用延迟执行语句在函数退出时释放资源 // 1 使用延迟并发解锁
readValue("这个函数复用的别人代码") // 2 使用延迟释放文件句柄
sFileName := "//home//liq-n//桌面//1.png" fmt.Println("1.png fileSize:" + strconv.FormatInt(int64(fileSize(sFileName))/1024,10) + "KB" ) // fmt.Println(fmt.Sprintf("%d",fileSize("//home//useName//桌面//1.png")))
}