Values
Copy values, owned values, shared values, borrows, and callable values in Walrus.
Walrus values are categorized by their ownership behavior. Understanding whether a value is copied or moved is key to writing efficient scripts.
Copy Values (Cheap)
These values are small and passed by value. Assigning them or passing them to a function creates an independent copy.
- Primitives:
int,float,bool - Enums: Named members like
Team.Red - Function Pointers:
fnvalues - References:
ref Tandmut ref T(the borrow itself is a copyable pointer) - Shared Handles:
shared<T>andhandle<T>(native engine handles)
let count = 45
let ok = true
let ratio = 2.0Owned Values (Heavy)
These values own heap-allocated data. To prevent expensive deep-copies, Walrus moves them on assignment.
string- Arrays: e.g.,
[1, 2, 3] - Objects: e.g.,
{ x = 1, y = 2 } - Class instances: Objects created from
classtemplates - Escaping Closures: Nested functions that capture owned state and are returned
let text = "walrus"
let moved = text # 'text' is now invalidBorrowed Values (ref)
Borrows provide a temporary view into an owned value without taking ownership.
ref T: Read-only access.mut ref T: Exclusive read-write access.
fn read_only(s: ref string):
print(s)
let name = "Walrus"
read_only(name) # 'name' remains validShared Values (shared<T>)
When multiple parts of a script need to share ownership of the same heap object (like a node in a tree), use shared<T>. This uses reference counting internally.
class Node:
var next: shared<Node>Native Handles (handle<T>)
Handles represent objects managed by the C++ engine (the host). They behave like copy-values but are validated by the engine before every use to prevent crashes if the engine object is deleted.
let player = Player.find("Hero") # Returns a handle
player.move_to(0, 0)Callable Values
Functions and closures are first-class values in Walrus.
fn makeAdder(k: int) -> fn(int) -> int:
fn add(x: int) -> int:
return x + k
return add