RAII =资源获取是初始化
Ref Counting =“穷人的GC”
在一起,它们非常强大(就像一个包含VBO的ref-counting 3D对象,它在调用析构函数时会抛出它)。
现在,问题是 - 除了C ++之外,RAII是否存在于任何语言中?特别是,一种不允许指针算术/缓冲区溢出的语言?
答案 0 :(得分:3)
D有RAII,但仍然有指针算术:(但是,你真的不必使用它。请注意让D工作对我来说是一个痛苦,所以我只是在说。
答案 1 :(得分:3)
虽然不完全是RAII,但Python有with statement而C#有using statement.
答案 2 :(得分:2)
Perl 5具有保证在所有引用都超出范围时被调用的引用计数和析构函数,因此RAII在语言中可用,尽管大多数Perl程序员不使用该术语。
Perl 5没有公开Perl代码的原始指针。
然而,Perl 6有一个真正的垃圾收集器,实际上允许垃圾收集器被切换掉;所以你不能依赖任何特定顺序收集的东西。我相信Python和Lua使用引用计数。
答案 3 :(得分:2)
perl,python(C),php和tcl是引用计数的,并且具有在引用计数变为零时销毁对象的机制,这可以在变量超出范围时立即发生。内置类型会自动释放。用户定义的类有一种方法可以定义在释放时调用的析构函数。
有一些边缘情况:全局变量可能直到结束时才会被释放,并且循环引用可能直到最后才被释放(尽管php最近实现了一个处理这种情况的gc并且python 2添加了一个循环检测器)。 / p>
答案 4 :(得分:2)
Python(标准的CPython,而不是像Jython,Unladen Swallow和IronPython这样的变体)对其对象使用引用计数。
有了它,它还具有RAII和(大多数)确定性垃圾收集。例如,这应该确定性地关闭文件:
def a():
fp = open('/my/file', 'r')
return fp.read()
注意永远不会调用fp.close()
。一旦fp
超出范围,对象就应该被销毁。但是,在某些情况下无法保证确定性的最终确定,例如:
sys.last_traceback
保留最后一个回溯)因此,虽然python在理论上具有确定性的最终化,但最好明确地关闭任何可能异常(如IOError等)可能导致对象保持活动的资源。
答案 5 :(得分:1)
Vala对象的内存管理基于引用计数,它具有RAII(从某种意义上说,它的析构函数是确定性的)。典型的用例是创建GUI,其中引用计数的开销通常可以忽略不计。您可以使用指针并绕过引用计数,例如,为了实现互操作性,或者如果您需要额外的性能,但在大多数情况下,您可以不使用指针。它也做了一些聪明的事情,你可以将引用标记为owned
或unowned
并转移所有权,并且在许多情况下它能够忽略引用计数(如果一个对象没有转义函数,例如)。 Vala与GObject / GTK紧密相连,所以只有你想在那个生态系统中工作才有意义。
另一个有趣的候选人是Rust。虽然它也有指针和垃圾收集,但两者都是可选的。您可以使用相当于C ++的智能指针完全编写程序,保证没有泄漏,并且它支持RAII。它也有像Vala一样的参考所有权概念,但有点复杂。从本质上讲,Rust可让您完全控制如何管理内存。您可以在裸机级别工作,甚至可以在其中编写内核,或者您可以使用GC或其间的任何内容进行高级别工作,并且大多数时候它可以保护您免受泄漏内存或其他指针的影响 - 相关的错误。缺点是它非常复杂,而且由于它仍在开发中,因此可能会发生变化。