go语言学习之延迟执行语句

// 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")))    
}