Assignment
An assignment stores a new value in a place that already exists — a var, a field, an element, or the target of a writable pointer.
| Operator | Meaning |
|---|---|
place = value | copy value into place |
place <- value | move value into place |
place += value, -=, *=, /=, %= | place = place + value, and so on |
place &= value, |=, ^= | the bitwise forms |
place <<= value, >>=, >>>= | the shift forms |
place++, ++place | add one |
place--, --place | subtract one |
var n: int32 = 10;
n += 5;
n -= 3;
n *= 4;
n /= 5;
n %= 5;
Each line starts from the result of the one before: 15, 12, 48, 9, 4.
The target
The left side must be an assignable place: a variable, a field (p.x), a tuple element (pair.0), an indexed element (values[i]), or a dereferenced pointer (*ptr). And it must be mutable — a var, or something reached through one, a &var reference or a *var pointer:
var p = Point { x: 1, y: 2 };
p.x += 10;
p.y++;
var values: int32[3] = [1, 2, 3];
values[1] *= 7;
| Target | Error |
|---|---|
a let | cannot modify immutable variable 'fixed' |
| a constant | cannot modify constant 'Limit' |
| a value that is not a place | operator '=' requires an assignable target, but its left operand has type 'int' |
| through a read-only pointer | cannot modify data through read-only pointer '*int' |
The error for a let comes with help: declare 'fixed' with 'var' to make it mutable.
Type rules
The value must have the place's type, or widen to it without loss — an integer of the same signedness and a smaller width, as in a binding. A compound assignment follows the rules of its operator, and its result must still fit the place:
var total: int32 = 0;
let big: int64 = 5;
total += big;
error: operator '+=' produces 'int64', which cannot be stored in target type 'int32'
total += big as int32 converts first. Mixing kinds is refused just as the plain operator would refuse it: on an int32, score += 1.5 is error: operator '+=' cannot combine left operand 'int32' with right operand 'float64', and on a uint8, u += 300 is error: integer literal is out of range for type 'uint8'.
An assignment produces no value
An assignment is a complete action, not a value. The grammar reads a = b = c from the right, as a = (b = c), but b = c has nothing to give a:
first = second = 7;
error: an assignment produces no value and cannot be chained
help: assign each target in its own statement
For the same reason = cannot stand in for == in a condition: if a = 5 { … } is refused, because the condition is not a bool.
++ and --
++ adds one and -- subtracts one. They apply to any integer or floating-point place, and need it to be mutable like any other assignment: on a let, k++ is error: cannot modify immutable variable 'k'.
On a line of its own, the prefix and postfix forms are the same. Used as a value, they differ in what they hand back:
| Form | Value of the expression | Afterwards |
|---|---|---|
count++ | the old value | one higher |
++count | the new value | one higher |
count-- | the old value | one lower |
--count | the new value | one lower |
var count: int32 = 1;
let before = count++;
let after = ++count;
PrintLine("{} {} {}", before, after, count);
This prints 1 3 3. Code that leans on the difference is easy to misread; most Rux code keeps ++ and -- on lines of their own.
Rux has no unary +, so a =+ 3 does not parse; and a =- 3 is a = -3, a valid assignment of minus three. The operator always comes before the =.
Moving with <-
place <- value moves instead of copying: the value is handed over and its source may not be read again. The place's old value is destroyed as it is replaced, just as with =:
let first = Buffer { size: 4 };
var second = Buffer { size: 0 };
second <- first;
Reading first afterwards is error: value 'first' is used after it was moved. A type that cannot be copied is assigned from a named source only with <-. When copy and move apply, and what replacing a value destroys, are covered in Copy and move.
See also
- Bindings — declaring the places that are assigned to
- Initialization — the first assignment of a
vardeclared without a value - Arithmetic — the operators inside the compound forms
- Copy and move —
=and<- - Learn: Assignment