Operators
Arithmetic
| Operator | Meaning | Example |
|---|---|---|
+ | addition | x + y |
- | subtraction | x - y |
* | multiplication | x * y |
/ | division | x / y |
% | modulo | x % y |
** | exponentiation | x ** y |
Comparison
| Operator | Meaning | Example |
|---|---|---|
== | equal | x == y |
!= | not equal | x != y |
< | less than | x < y |
<= | less than or equal | x <= y |
> | greater than | x > y |
>= | greater than or equal | x >= y |
Logical
| Operator | Meaning | Example |
|---|---|---|
and | logical AND (short-circuit) | x and y |
or | logical OR (short-circuit) | x or y |
not | logical NOT | not x |
and and or are keywords, not symbols. They short-circuit: the right operand is only evaluated if needed.
Bitwise
| Operator | Meaning | Example |
|---|---|---|
& | bitwise AND | x & y |
^ | bitwise XOR | x ^ y |
~ | bitwise NOT | ~x |
<< | left shift | x << y |
>> | right shift | x >> y |
Unary
| Operator | Meaning | Example |
|---|---|---|
- | negation | -x |
not | logical NOT | not x |
~ | bitwise NOT | ~x |
Precedence
From highest to lowest binding power:
| Precedence | Operators | Associativity |
|---|---|---|
| 25 | . () ? | left (postfix) |
| 21 | - not ~ (unary) | prefix |
| 19 | ** | right |
| 17 | * / % | left |
| 15 | + - | left |
| 13 | << >> | left |
| 11 | & | left |
| 9 | ^ | left |
| 7 | == != < <= > >= | left |
| 5 | and | left |
| 3 | or | left |
| 1 | = += -= *= /= %= | right |
Parentheses override precedence:
x + y * z // y * z first
(x + y) * z // x + y first
-a + b ** 2 // (-a) + (b ** 2)
Compound Assignment
| Operator | Desugars to |
|---|---|
x += y | x = x + y |
x -= y | x = x - y |
x *= y | x = x * y |
x /= y | x = x / y |
x %= y | x = x % y |
Works on fields too:
p.x += 10 // p = Point { x: p.x + 10, ..p }
lexer.pos += len
Try Operator
The postfix ? operator propagates errors from Result values:
fn read_config(path: String) -> Result<Config, Error>:
let contents = read_file(path)? // returns Err early if read fails
let config = parse(contents)?
Ok(config)
? desugars to a match on the Try trait — on Err, it returns the error; on Ok, it unwraps the value.
Chaining:
fn combine(x: Result<i64, String>, y: Result<i64, String>) -> Result<i64, String>:
Ok(x? + y?)