golang

  • Go 语言中使用 defer 的几个场景

    2018-05-20 15:04:16 1215 0 技术文章

    简化资源回收,相当于析构函数

    在 Go 语言中,没有析构函数,如果需要在实例完成后进行资源回收的情况,可以使用 defer 语句。 defer 是先进后出,这样做很合理,后面的语句会依赖前面的资源,如果先前面的资源先释放了,那后面的语句就没法执行了。 当然, defer 也有一定的开销, 也有为了节省性能而回避使用的 defer 的。 使用示例:

    func set(mu *sync.Mutex, i int) {
        mu.Lock()
        mu.Unlock()
    }
    

    panic 异常捕获,recover 只能在 defer 语句中使用

    使用方法如下:

    func main() {
        defer func() {
            if r := recover(); r != nil {
                fmt.Println(r)
            }
        }()
        panic("Error")
    }
    

    修改返回值,适用于特定场景

    func doubleSum(a, b int) (sum int) {
        defer func() {
            sum *= 2
        }()
        sum = a + b
    }
    

    安全回收资源,即使 panic 抛出异常,recover 也可捕获

    不使用 defer 的情况,前面的语句出现异常,后面的语句就没有机会执行。

    func set(mu *sync.Mutex, i, v int) {
        mu.Lock()
        i := v / 0 // 0 不能做除数,会抛出异常,后面的语句不能被执行
        mu.Unlock()
    }
    

    使用 defer 的情况,即使前面出现异常,后面的语句照样可以执行。

    func set(mu *sync.Mutex, i, v int) {
        mu.Lock()
        i := v / 0 // 0 不能做除数,会抛出异常,后面的语句不能被执行
        mu.Unlock()
    }