Перейти к содержанию

Введение в жизненный цикл значений

До сих пор мы объясняли, как Mojo позволяет создавать высокопроизводительный код, безопасный для памяти, без ручного управления памятью, используя модель владения Mojo. Однако Mojo предназначен для системного программирования, которое часто требует ручного управления памятью для пользовательских типов данных. Итак, Mojo позволяет вам делать это по своему усмотрению. Для ясности, в Mojo нет счетчика ссылок и сборщика мусора.

Mojo также не имеет встроенных типов данных со специальными привилегиями. Все типы данных в стандартной библиотеке (такие как Bool, Int и String) реализованы в виде структур.

Что самое замечательное в языке Mojo, так это то, что он предоставляет вам эти низкоуровневые инструменты для системного программирования, но в рамках структуры, которая помогает вам создавать безопасные и простые в использовании вещи из программ более высокого уровня. То есть вы можете залезть под капот и написать любой "небезопасный" код, какой захотите, но до тех пор, пока вы делаете это в соответствии с семантикой значений Mojo, программисту, создающему экземпляр вашего типа / объекта, вообще не нужно думать об управлении памятью, и поведение будет безопасным и понятным. предсказуемо, благодаря ценному владению.

Таким образом, автор типа несет ответственность за управление памятью и ресурсами для каждого типа значений, реализуя при необходимости определенные методы жизненного цикла, такие как конструктор, конструктор копирования, конструктор перемещения и деструктор. Mojo по умолчанию не создает никаких конструкторов, хотя и добавляет тривиальный деструктор без операций для типов, которые не определяют свои собственные.

На следующих страницах мы подробно объясним, как определить эти методы жизненного цикла в соответствии с семантикой значений, чтобы ваши типы хорошо сочетались с принадлежностью значений.

Жизненные циклы и сроки службы

Сначала давайте проясним некоторую терминологию:

  • "Жизненный цикл" значения определяется различными методами с двойным подчеркиванием в структуре. Каждое событие жизненного цикла обрабатывается разными методами, такими как конструктор (__init__()), деструктор (__del__()), конструктор копирования (__copyinit__()) и конструктор перемещения (__moveinit__()). Все значения, объявленные с одинаковым типом, имеют одинаковый жизненный цикл.

  • "Время жизни" переменной определяется промежутком времени во время выполнения программы, в течение которого переменная считается допустимой. Срок службы переменной начинается, когда ее значение инициализируется (с помощью __init__(), __copyinit__() или __moveinit__()) и заканчивается, когда значение уничтожается (__del__()) или используется каким-либо другим способом (например, как часть вызова __moveinit__()).

Нет двух значений с одинаковым временем жизни, потому что каждое значение создается и уничтожается в разный момент времени (даже если разница незаметна).

Исходный тип Понятие времени жизни связано с типом origin, примитивом Mojo, используемым для отслеживания владельца. Для большинства программ Mojo вам не нужно будет напрямую работать со значениями origin.

Срок службы значения в Mojo начинается с момента инициализации переменной и продолжается до тех пор, пока значение не будет использовано в последний раз, после чего Mojo уничтожает его. Mojo уничтожает каждое значение/объект, как только оно больше не используется, используя политику уничтожения “как можно скорее” (ASAP), которая выполняется после каждого вложенного выражения. Компилятор Mojo при необходимости освобождает ресурсы после последнего использования.

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