References & Borrowing
18.1 Immutable and mutable references
fun sum(v: &vector<u64>): u64 { // read-only borrow
let mut total = 0;
let mut i = 0;
while (i < v.length()) { total = total + v[i]; i = i + 1; };
total
}
fun double_all(v: &mut vector<u64>) { // mutable borrow
let mut i = 0;
while (i < v.length()) {
let e = &mut v[i];
*e = *e * 2;
i = i + 1;
};
}
fun demo() {
let mut v = vector[1, 2, 3];
double_all(&mut v);
let s = sum(&v); // 12
}18.2 Reference operations
&x, &s.field &mut x, &mut s.field x declared let mut (Sui 2024) Read through ref Type must have copy Write through ref Old value must have drop
freeze(r) or implicit &mut T to &T r.field, &r.field, &mut r.field Inside defining module
18.3 Borrow rules
Many &T or one &mut T to the same location at a time (the borrow checker enforces this).
References cannot be stored in structs, globals, or vectors.
References cannot outlive what they point to: you cannot return a reference to a local variable. You can return references derived from reference parameters:
Because references never escape a transaction and there is no dynamic dispatch, Move has no re-entrancy and no dangling pointers.
public fun first(v: &vector<u64>): &u64 { &v[0] } // OK
// public fun bad(): &u64 { let x = 1; &x } // ERROR18.4 Passing objects by reference vs value (Sui)
Meaning for objects Read-only access; works for owned, shared, and immutable objects
Mutate; owned or shared objects (not immutable) Take ownership; caller loses it; must be consumed (transfer, wrap, delete). Shared objects can be taken by value only to delete them or re-share in the same transaction