Существует ли язык с RAII + Ref подсчетом, который не имеет небезопасного указателя арифметического?


RAII = получение ресурсов является инициализацией

Ref подсчет = "GC бедняка"

Вместе они довольно мощные (например, 3D-объект с реф-счетом, содержащий VBO, который он выбрасывает, освобождается, когда вызывается деструктор).

Теперь вопрос : существует ли RAII в каком-либо языке, кроме C++? В частности, язык, который не допускает арифметического переполнения указателя / буфера?

6 6

6 ответов:

Perl 5 имеет подсчет ссылок и деструкторы, которые гарантированно вызываются, когда все ссылки выпадают из области видимости, поэтому RAII доступен в языке, хотя большинство программистов Perl не используют этот термин.

И Perl 5 не предоставляет необработанные указатели для кода Perl.

Perl 6, однако, имеет реальный сборщик мусора и фактически позволяет сборщику мусора отключаться; поэтому вы не можете полагаться на вещи, собираемые в каком-либо определенном порядке.

Я верю питону и Луа используйте подсчет ссылок.

D имеет RAII, но все еще имеет арифметику указателей : (но, на самом деле, вам не нужно ее использовать. Пожалуйста, обратите внимание, что получение D на работу было болью в заднице для меня, поэтому я просто говорю.

Хотя и не совсем RAII, Python имеет оператор with, А C# имеет оператор using.

Perl, python (C), php и tcl подсчитывают ссылки и имеют механизмы для уничтожения объекта, как только его счетчик ссылок становится равным нулю, что может произойти, как только переменная выходит за пределы области видимости. встроенные типы выпускаются автоматически. определяемые пользователем классы имеют способ определить деструктор, который будет вызван при выпуске.

Есть несколько крайних случаев: глобальные переменные могут не быть выпущены до конца, а циклические ссылки могут не быть выпущены до конца (хотя php имеет недавно был реализован gc, который обрабатывает этот случай, и python 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 или подобное) может вызвать цель-остаться в живых.

Управление памятью объектов Vala основано на подсчете ссылок, и оно имеет RAII (в том смысле, что его деструкторы называются детерминистически). Типичный пример использования-создание GUI, где накладные расходы от пересчета часто незначительны. Вы можете использовать указатели и обходить пересчет, например, для взаимодействия или если вам нужна дополнительная производительность, но в большинстве случаев вы можете жить без указателей. Он также делает что-то умное, вы можете отметить ссылки как owned или unowned и передавать права собственности, и во многих случаях он способен элидировать подсчет ссылок (если объект не избегает функции, например). Vala тесно связана с GObject/GTK, поэтому ее имеет смысл использовать только в том случае, если вы хотите работать в этой экосистеме.

Еще одним интересным кандидатом может бытьржавчина . Хотя он также имеет указатели и сборку мусора, оба являются необязательными. Вы можете писать программы полностью с эквивалентом интеллектуальных указателей C++, с гарантированным отсутствием утечка, и он поддерживает RAII. У него также есть концепция референтного владения, как у вала, но немного более сложная. По сути, Rust дает вам полный контроль над тем, как вы управляете памятью. Вы можете работать на уровне голого металла и даже написать ядро в нем, или вы можете работать на высоком уровне с GC, или что-нибудь между ними, и большую часть времени это защищает вас от утечки памяти или других ошибок, связанных с указателями. Недостатком является то, что он довольно сложен, и так как он все еще находится в разработке все может измениться.