区分失败 - 退出和成功退出在某些时候是非常有用的 - 我没有D的真实世界经验,但是Python的 with 语句也允许这样做,并且我发现它非常有用,例如,提交或回滚在正文的受保护部分中打开的数据库事务 .
当我解释这个新的Python特性(它现在已经存在一段时间了;-)给了C和Java大师的朋友和同事时,我发现他们立即理解了,并且看到了对这样一个特性的兴趣(Python确实有 finally ,但是's no help in distinguishing success from failure, just like in other languages [or C++' s "RAII destruction of auto variables in the block"等效]) .
6 回答
免责声明我也是D粉丝男孩 .
相比:
try / catch /最终强制嵌套;范围守卫没有 . 此外,它们允许您在与分配代码相同的“区域”中编写清理代码,因此不再需要“打开文件,滚动到功能结束,关闭文件,滚动到功能顶部” .
从根本上说,它只是一个更方便的try / catch / finally异常处理表达式 - 你可以用try / catch /最后做任何事情,你可以用范围保护,反向 .
这值得么?我是一个D粉丝(所以,有偏见),但我肯定会说 .
scope(X)
不一定需要for
,只要你有if
和goto
.这是我今天写的一些代码中的一个释义示例:
将此与使用try / catch进行对比:
代码变成spaghetti,在整个商店中传播错误恢复并强制每个try块的缩进级别 . 在我看来,使用范围(X)的版本更易读,更容易理解 .
值得一提的是,范围(退出),范围(失败)和范围(成功)也可用于C.
对于范围(退出),有Boost.ScopeExit库 .
对于范围(失败)和范围(成功),有stack_unwinding库 .
支持以下语法,案例1:
打印:
案例2:
打印:
区分失败 - 退出和成功退出在某些时候是非常有用的 - 我没有D的真实世界经验,但是Python的
with
语句也允许这样做,并且我发现它非常有用,例如,提交或回滚在正文的受保护部分中打开的数据库事务 .当我解释这个新的Python特性(它现在已经存在一段时间了;-)给了C和Java大师的朋友和同事时,我发现他们立即理解了,并且看到了对这样一个特性的兴趣(Python确实有
finally
,但是's no help in distinguishing success from failure, just like in other languages [or C++' s "RAII destruction of auto variables in the block"等效]) .@DK,应该指出,在C(和Java我认为)中你可以轻松地使用“匿名”类来完成与scope(exit)相同的事情:
如果您不止一次这样做,您会立即将其变成一个完整的课程来为您处理RAII . 编写起来非常简单我无法想象使用sqlite的C程序(如示例中所使用的)而不创建类似CSqlite_DB和CSqlite_Stmt的类 . 事实上,运算符sqlite3 *()应该是anathama,完整版本只有提供语句的方法:
至于原来的问题,我会说答案是“不是真的” . 正确尊重DRY会告诉你把那些长块的try / catch / finally转换成单独的类,将try / catch部分隐藏起来,远离其他部分(在范围(失败)的情况下)并制作资源管理透明(在范围(退出)的情况下) .