要理解延迟,您需要了解替代方法。
在复杂的代码处理许多资源,你最终会做这样的(伪代码)的东西:
mtx.Lock()
file1, err := os.Open(...)
if err != nil {
mtx.Unlock()
return err
}
conn, err := net.Dial(...)
if err != nil {
file1.Close()
mtx.Unlock()
return err
}
file2, err := os.Open(...)
if err != nil {
conn.Close()
file1.Close()
mtx.Unlock()
return err
}
do_things()
file2.Close()
conn.Close()
file1.Close()
mtx.Unlock()
return nil
这得到详细的快。而且,从长期来看,它很容易出错,因为有人编辑代码,并可能在打开file1之前将网络连接的开放移动到可能无法正确更新所有错误处理路径。
在C,这里常见的成语是收集资源的全部清理在函数的末尾,做这样的事情:
ret = ERROR;
lock(mtx);
fd1 = open(...);
if (fd1 == -1)
goto err1;
conn = net_conn(...);
if (conn == -1)
goto err2;
fd2 = open(...);
if (fd2 == -1)
goto err3;
do_things();
ret = 0;
close(fd2);
err3:
close(conn);
err2:
close(fd1);
err1:
unlock(mtx);
return ret;
这是不漂亮或者,它是很容易得到这个也是错的。
作为比较做同样的事情有延迟,我们得到:
mtx.Lock()
defer mtx.Unlock()
file1, err := os.Open(...)
if err != nil {
return err
}
defer file1.Close()
conn, err := net.Dial(...)
if err != nil {
return err
}
defer conn.Close()
file2, err := os.Open(...)
if err != nil {
return err
}
defer file2.Close()
.... do things ...
return nil
很清晰,简洁,谁知道去就会明白发生了什么,这是非常难拿错或将来打破。
来源
2017-10-09 09:38:04
Art