8.1.17. Move, Copy, and Clone

This tutorial covers the three assignment operators: copy (=), move (<-), and clone (:=), when to use each, and how types determine operator availability.

8.1.17.1. Copy (=)

Bitwise copy. Source unchanged. Works for POD types (int, float, string) and POD-only structs:

let a = 42
let b = a         // b is 42, a is still 42

8.1.17.2. Move (<-)

Transfers ownership. Source is zeroed. Use for containers (array, table), lambdas, and iterators:

var nums <- [1, 2, 3]
let other <- nums       // other owns the array, nums is empty

Functions returning containers must use return <-:

def make_data() : array<int> {
    var result : array<int>
    result |> push(1)
    return <- result
}

8.1.17.3. Clone (:=)

Deep copy. Both sides remain valid and independent:

var original : array<int>
original |> push(1)
original |> push(2)

var copy : array<int>
copy := original        // deep copy
copy |> push(999)       // does not affect original

Clone initialization:

let another := original

8.1.17.4. Type compatibility

Type

=

<-

:=

int, float, POD

Yes

Yes

Yes

string

Yes

Yes

Yes

array, table

No

Yes

Yes

lambda

Yes (alias)

Yes

No

iterator

No

Yes

No

block

No

No

No

Note

= on a lambda copies the fat pointer — both variables share the same capture frame (aliasing, not an independent copy). See Lambdas and Closures for details.

8.1.17.5. Relaxed assign

By default, the compiler auto-promotes = to <- when the right side is temporary (literal, function return). Disable with options relaxed_assign = false.

8.1.17.6. Struct field initialization

Each field can use a different mode:

var weapons : array<string>
weapons |> push("bow")

let loadout = Inventory(items <- weapons, weight = 5)
// weapons is now empty after the move

8.1.17.7. Custom clone functions

Override clone behavior by defining a clone function for your type:

struct GameState {
    level : int
    score : int
}

def clone(var dst : GameState; src : GameState) {
    dst.level = src.level + 1000   // custom logic during clone
    dst.score = src.score
}

var original = GameState(level=5, score=100)
let copy := original    // invokes custom clone
// copy.level is 1005, not 5

See also

Move, Copy, and Clone in the language reference.

Full source: tutorials/language/17_move_copy_clone.das

Next tutorial: Classes and Inheritance