This repository has been archived on 2025-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
rhaj/rhai_engine/rhaibook/language/assignment.md
2025-04-03 09:18:05 +02:00

3.0 KiB

Assignments

{{#include ../links.md}}

Value assignments to [variables] use the = symbol.

let foo = 42;

bar = 123 * 456 - 789;

x[1][2].prop = do_calculation();

Valid Assignment Targets

The left-hand-side (LHS) of an assignment statement must be a valid l-value, which must be rooted in a [variable], potentially extended via indexing or properties.


Expressions that are not valid _l-values_ cannot be assigned to.

```rust
x = 42;                 // variable is an l-value

x[1][2][3] = 42         // variable indexing is an l-value

x.prop1.prop2 = 42;     // variable property is an l-value

foo(x) = 42;            // syntax error: function call is not an l-value

x.foo() = 42;           // syntax error: method call is not an l-value

(x + y) = 42;           // syntax error: binary op is not an l-value
```

Values are Cloned

Values assigned are always cloned. So care must be taken when assigning large data types (such as [arrays]).

x = y;                  // value of 'y' is cloned

x == y;                 // both 'x' and 'y' hold different copies
                        // of the same value

Moving Data

When assigning large data types, sometimes it is desirable to move the data instead of cloning it.

Use the take function (defined in the [LangCorePackage][built-in packages] but excluded when using a [raw Engine]) to move data.

The original variable is left with ()

x = take(y);            // value of 'y' is moved to 'x'

y == ();                // 'y' now holds '()'

x != y;                 // 'x' holds the original value of 'y'

Return large data types from functions

take is convenient when returning large data types from a [function].

fn get_large_value_naive() {
    let large_result = do_complex_calculation();

    large_result.done = true;

    // Return a cloned copy of the result, then the
    // local variable 'large_result' is thrown away!
    large_result
}

fn get_large_value_smart() {
    let large_result = do_complex_calculation();

    large_result.done = true;

    // Return the result without cloning!
    // Method style call is also OK.
    large_result.take()
}

Assigning large data types to object map properties

take is useful when assigning large data types to [object map] properties.

let x = [];

// Build a large array
for n in 0..1000000 { x += n; }

// The following clones the large array from 'x'.
// Both 'my_object.my_property' and 'x' now hold exact copies
// of the same large array!
my_object.my_property = x;

// Move it to object map property via 'take' without cloning.
// 'x' now holds '()'.
my_object.my_property = x.take();

// Without 'take', the following must be done to avoid cloning:
my_object.my_property = [];

for n in 0..1000000 { my_object.my_property += n; }