Operators
Operators work on values of one type at a time: both operands of a binary operator have the same type, with literals taking the type of the other side. They follow Rust and C, with a few exceptions noted below.
Precedence
Section titled “Precedence”From the tightest to the loosest. All binary operators are left-associative:
a - b - c is (a - b) - c.
| precedence | operators | kind |
|---|---|---|
| 1 | f(x) a[i] s.x |
call, index, field |
| 2 | -x !x *p &x ref x comptime x |
prefix |
| 3 | x as T |
conversion |
| 4 | * / % |
multiplicative |
| 5 | + - |
additive |
| 6 | << >> |
shift |
| 7 | & |
bitwise and |
| 8 | ^ |
bitwise xor |
| 9 | | |
bitwise or |
| 10 | < <= > >= |
ordering |
| 11 | == != |
equality |
| 12 | && |
logical and |
| 13 | || |
logical or |
As in Rust and unlike C, comparisons bind looser than the bitwise operators, so
x & 1 == 0 is (x & 1) == 0. Unlike Rust, ordering binds tighter than
equality, so a < b == c < d compares two bools.
A prefix operator applies to everything after it at its level: comptime a * b
is (comptime a) * b, so write comptime (a * b) for a whole product.
Arithmetic
Section titled “Arithmetic”| operator | operands | result |
|---|---|---|
+ - * |
integers, floats | the same type; integers wrap around |
/ % |
integers, floats | integers truncate; floats per IEEE (% is fmod) |
-x |
signed integers, floats | negation |
+ |
str, str |
concatenation (hosted) |
+ |
[T], [T] |
a new list of both lists’ elements (hosted) |
+ - |
*T and i64 |
a pointer moved by whole elements (Pointers) |
See Types for overflow and division by zero.
Comparison
Section titled “Comparison”| operator | operands | result |
|---|---|---|
== != |
any type made of comparable parts | bool (Equality) |
< <= > >= |
integers, floats, pointers of the same type; str; two values of a type with an Ord |
bool |
Integers compare signed or unsigned according to their type, and pointers by
address; strings compare byte by byte, a prefix first. Other types are ordered
by their Ord: a < b is a.compare(b) < 0, so structs,
enums, tuples, lists and options order once they or their parts have one.
Arrays have no ordering.
Bitwise
Section titled “Bitwise”| operator | operands | result |
|---|---|---|
& | ^ |
integers | bitwise and, or, xor |
& | ^ |
bools | and, or, xor — both sides are always evaluated |
!x |
integers | every bit flipped (Rust’s !, C’s ~) |
<< >> |
integers of one type | shift |
>> is arithmetic (sign-filling) for signed types and logical for unsigned
ones. The shift amount is taken modulo the bit width, so x << 64 on an i64
is x, on the VM and natively alike.
Logical
Section titled “Logical”| operator | operands | result |
|---|---|---|
&& || |
bools | and, or — the right side is only evaluated if needed |
!x |
bool | not |
Pointers and references
Section titled “Pointers and references”| operator | meaning | page |
|---|---|---|
&place |
the address of a variable, field or element | Pointers |
*p |
what a pointer, ref or cell holds |
Pointers, References, Cells |
ref e |
a new reference to a copy of e |
References |
Not operators
Section titled “Not operators”Assignment is a statement, not an operator: = and the compound assignments
+=, -=, *=, /=, %=, &=, |=, ^=, <<= and >>=
(Variables and control flow) cannot be
used inside expressions.
There is no increment (++), no ternary ?: (use a
match expression), and no operator
overloading.