学做网站论坛vip共享,前端开发培训中心,长沙品牌设计公司都有哪些,网络推广优化平台目录
1、资源释放
2、异常捕获
3、参数的预计算
4、defer 返回值的陷阱 1、资源释放
下面是一个简单的读取文件的程序#xff0c;os.Open 打开文件资源描述符#xff0c;在读取文件后#xff0c;需要释放资源。但是在错误的时候#xff0c;程序就直接返回那么#xf…目录
1、资源释放
2、异常捕获
3、参数的预计算
4、defer 返回值的陷阱 1、资源释放
下面是一个简单的读取文件的程序os.Open 打开文件资源描述符在读取文件后需要释放资源。但是在错误的时候程序就直接返回那么资源就得不到释放
func ReadFile(Filename string) ([]byte, error) {file, err : os.Open(Filename)if err ! nil {return nil, err}stat, err : file.Stat()if err ! nil {return nil, err}var re make([]byte, stat.Size())_, err file.Read(re)if err!nil{return nil,err}file.Close()if err ! nil {return nil, err}return re, nil
}
那么程序需要就需要修改为在所有err 的地方都需要释放资源
file, err : os.Open(Filename)
if err ! nil {file.Close()return nil, err
}stat, err : file.Stat()if err ! nil {file.Close()return nil, err}var re make([]byte, stat.Size())_, err file.Read(re)if err ! nil {file.Close()return nil, err}
但是这样处理很不优雅而且很容易漏掉那么我们就可以利用defer 的延迟调用,程序结束的时候释放资源,能减少大量冗余代码避免由于忘记释放资源而产生的错误
func ReadFile(Filename string) ([]byte, error) {file, err : os.Open(Filename)defer file.Close()if err ! nil {return nil, err}stat, err : file.Stat()if err ! nil {return nil, err}var re make([]byte, stat.Size())_, err file.Read(re)if err ! nil {return nil, err}if err ! nil {return nil, err}return re, nil
} 2、异常捕获
避免程序因为panic 异常退出可以通过defer函数中使用recover进行异常捕获程序就不会异常退出main的 fmt.Println 可以打印
func ReadFile(Filename string) ([]byte, error) {file, err : os.Open(Filename)defer file.Close()if err ! nil {return nil, err}stat, err : file.Stat()if err ! nil {return nil, err}var re make([]byte, stat.Size())_, err file.Read(re)if err ! nil {return nil, err}if err ! nil {return nil, err}return re, nil
} 3、参数的预计算
传递到defer 中的函数参数是预执行的因此在执行 defer 语句时执行了a1并将其保留下来只到函数执行完后才执行 defer 函数体内的语句。
func main() {a : 1defer func(b int) {fmt.Println(b)}(a 1)a 100
} 4、defer 返回值的陷阱
有返回值时时先执行defer 还是先执行 return 具体情况具体分析先看几个例子
var g 100
func gf() (r int) {defer func() {g 200}()fmt.Printf(g:%d\n, g)return g
}
func main() {i : gf()fmt.Println(i)fmt.Println(g)
}
g:100
100
200
从返回结果看好像是先执行了return 在执行了 defer
那么下面的程序
var g 100
func gf() (r int) {r gdefer func() {r 200}()r 0return r
}
func main() {i : gf()fmt.Println(i)fmt.Println(g)
}
返回结构
200
100
从返回结果好像是先执行了defer 后执行了 return
那么为什么会这样呢原因是return 不是一个原子操作包含了下面几步
将返回值保存在栈上-执行defer 函数-函数返回
对于第一个例子
g100
rg
g200
return
对于第二个例子
g100
rg
g200
return