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

Семантика значений

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

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

Введение в семантику значений

В самой простой ситуации совместное использование семантического типа значения означает, что вы создаете копию значения. Это также известно как "передача по значению". Например, рассмотрим этот код:

def main():
    var x = 1
    var y = x
    y += 1

    print("x:", x)
    print("y:", y)
x: 1
y: 2

Мы присвоили x значение y, что создает значение для y путем создания копии x. Когда мы увеличиваем y, значение x не меняется. Каждая переменная обладает исключительным правом собственности на значение.

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

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

Семантика значений в функциях Mojo

Семантика значений также применяется к аргументам функций в Mojo по умолчанию. Однако способ их применения отличается в зависимости от соглашения об использовании аргументов, которое обсуждается на странице Владения.

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

fn add_two(y: Int):
    # y += 2  # это привело бы к ошибке компилятора, потому что `y` является неизменяемым
    # Вместо этого мы можем сделать явную копию:
    var z = y
    z += 2
    print("z:", z)

def main():
    var x = 1
    add_two(x)
    print("x:", x)
z: 3
x: 1

Все это согласуется с семантикой значений, поскольку каждая переменная сохраняет уникальное право собственности на свое значение.

Способ, которым функция получает значение y, - это подход к семантике значений "смотри, но не трогай". Это также более экономичный с точки зрения памяти подход при работе с аргументами, требующими больших затрат памяти, поскольку Mojo не создает никаких копий, если мы сами явно не создаем копии.

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

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

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

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