Literals and Operators
Integers 1, floats 1.2, imaginary numbers 3i, runes 'a', strings "abc", booleans true, and the nil value.
Integers can be expressed using binary, octal, decimal, dozenal, or hexadecimal notation using either of these prefixes: 0b, 0o, 0d, 0z, or 0x, respectively.
Underscores can be inserted in numeric literals to improve readability, e.g. 1_000 is the same as 1000, and0b1010_1110is the same as 0b10101110.
Number literals and constants in Odin "just work" in that if a constant is "untyped", it can convert to the appropriate type.
import "fmt.odin";
main :: proc() {
FOO :: 123; // named "untyped" constant
BAR: int : 456; // named constant of type `int`
// Constant values are calculated at compile time rather than runtime.
DUH :: FOO + BAR; // `DUH` will be of type `int` because `BAR` is typed
// Addition
fmt.println("1+1 =", 1 + 1);
// Subtraction
x: i32 = 1;
fmt.println("1-2 =", x-2);
// TODO: Try changing the type of the constant `x` to `u32` and see what happens
// TODO: Try changing `x` to a variable rather than a constant and change the type to `u32`
// Short-circuiting boolean logic
fmt.println("true AND false is", true && false);
fmt.println("true OR false is", true || false);
fmt.println("NOT true is", !true);
// Bitwise operations
fmt.printf("0011 AND 0101 is %b\n", 0b0011 & 0b0101);
fmt.printf("0011 OR 0101 is %b\n", 0b0011 | 0b0101);
fmt.printf("0011 XOR 0101 is %b\n", 0b0011 ~ 0b0101);
fmt.printf("0011 AND-NOT 0101 is %b\n", 0b0011 &~ 0b0101);
fmt.printf(Complement of 0011 is %b\n, ~cast(byte)i); // enforce `byte` and not default `int`
fmt.printf("1 << 5 is", 1 << 5);
fmt.printf("0x70 >> 2 is", 0x70 >> 2);
// Use underscores for readability
fmt.println("One billion is", 1_000_000_000);
// Complex numbers
c1: complex64 = 1 + 2i; // Complex numbers
c2 := 3 + 4i; // default type `complex128`
c3 := complex(3, 4); // Alternate form
c3_real := real(c3); // Returns the real component of `c3`
c3_imag := imag(c3); // Returns the imaginary component of `c3`
fmt.println("A complex number: " c3);
// Extended complex numbers
q1: quaternion128 = 1 + 2i + 3j - 4k; // Quaternion literal
q2 := 1 + 3j; // default type `quaternion256`
q3 := quaternion(1, -, 3, -4); // Alternate form
q3_real := real(c3); // Returns the real component of `q3`
q3_imag := imag(c3); // Returns the i-imaginary component of `q3`
q3_jmag := jmag(c3); // Returns the j-imaginary component of `q3`
q3_kmag := kmag(c3); // Returns the k-imaginary component of `q3`
fmt.println("A quaternion number: " c3);
}
Strings
There two kinds of string literals, escaped and raw.
// An escaped string can only be on one line
x := "Escaped string\n";
// A raw string can cover multiple lines
y := `Raw string
`;
// String literals can be automatically merged if necessary
z := "Append one string" " with another really easily";
Unary Operators
Left association unary operators have the highest precedence, then right association unary operators.
| Operator(s) | Description | Associates |
|---|---|---|
| ^ | Address | Right |
| ^ | Dereference | Left |
| + - ! ~ | Add, Negate, Not, Complement | Right |
Note: -x^ is evaluated like -(x^).
Binary Operators
If an operator has the same precedence, the evaluation order will be left to right.
| Precedence | Operator(s) | Description | ||
|---|---|---|---|---|
| 2 | \ | \ | Logical or | |
| 3 | && | Logical and | ||
| 4 | == != < > <= >= | Comparison | ||
| 5 | + - \ | ~ | Add, Subtract, Bitwise or, Bitwise xor | |
| 6 | * / % %% & &~ << >> | Multiple, Divide, Modulo Dividend, Modulo Divisor, Bitwise and, Bitwise and not, Left shift, Right shift |
Ternary Operators
| Precedence | Operator(s) | Description |
|---|---|---|
| 1 | ?: | Conditional |
?: is the only ternary operator in Odin. It can be used as an inline if statement.
cond := true;
x := cond ? 123 : 321;
If the condition and values are constant, then the ternary expression can be evaluated at compile time.
MAGIC :: ODIN_OS == "windows" ? 1001 : 1000;