我注意到 RAII 在 Stackoverflow 上引起了很多关注,但在我的圈子(主要是 C++)中,RAII 非常明显,就像问什么是类或析构函数一样。
所以我真的很好奇这是因为我每天都被铁杆 C++ 程序员包围,而 RAII 通常并不为人所知(包括 C++),还是因为对 Stackoverflow 的所有这些质疑都是由于是因为我现在接触的程序员不是用 C++ 长大的,而在其他语言中,人们只是不使用/不了解 RAII?
最佳答案
RAII 不为人所知的原因有很多。首先,名字不是特别明显。如果我还不知道 RAII 是什么,我肯定永远不会从名字中猜到它。 (资源获取是初始化?这与析构函数或清理有什么关系,这真正是 RAII 的特征?)
另一个是它在没有确定性清理的语言中效果不佳。
在 C++ 中,我们确切地知道何时调用析构函数,知道调用析构函数的顺序,并且可以定义它们来做任何我们喜欢的事情。
在大多数现代语言中,所有内容都是垃圾收集的,这使得 RAII 的实现更加棘手。没有理由不能将 RAII 扩展添加到 C# 中,但它不像 C++ 中那样明显。但正如其他人所提到的,Perl 和其他语言虽然被垃圾回收,但仍支持 RAII。
也就是说,仍然可以使用 C# 或其他语言创建您自己的 RAII 样式的包装器。我不久前在 C# 中做过。
我必须写一些东西来确保数据库连接在使用后立即关闭,这是任何 C++ 程序员都会认为是 RAII 的明显候选者的任务。
当然,每当我们使用数据库连接时,我们都可以将所有内容包装在 using
-statements 中,但这很麻烦且容易出错。
我的解决方案是编写一个辅助函数,它以委托(delegate)作为参数,然后在调用时打开数据库连接,并在 using 语句中将其传递给委托(delegate)函数,伪代码:
T RAIIWrapper<T>(Func<DbConnection, T> f){
using (var db = new DbConnection()){
return f(db);
}
}
仍然不如 C++-RAII 好或明显,但它实现了大致相同的东西。每当我们需要一个 DbConnection 时,我们都必须调用这个帮助函数来保证它之后会被关闭。
关于c++ - 除了 C++ 之外,其他语言的程序员是否使用、了解或理解 RAII?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/165723/