Enums
Tolk supports enums, similar to TypeScript and C++ enums.
In the TVM, all enums are represented as integers. At the compiler level, an enum is a distinct type.
// will be 0 1 2
enum Color {
Red
Green
Blue
}Enum members
Values can be specified manually. Otherwise, they are auto-calculated as +1.
enum Mode {
Foo = 256,
Bar, // implicitly 257
}Enum types
Enums are distinct types, not integers. Color.Red has type Color, not int, although it holds the value 0 at runtime.
fun isRed(c: Color) {
return c == Color.Red
}
fun demo() {
isRed(Color.Blue); // ok
isRed(1); // error, pass `int` to `Color`
}Since enums are types, they can be:
- used as variables and parameters,
- extended with methods,
- used in struct fields, unions, generics, and other type contexts.
struct Gradient {
from: Color
to: Color? = null
}
fun Color.isRed(self) {
return self == Color.Red
}
var g: Gradient = { from: Color.Blue };
g.from.isRed(); // false
Color.Red.isRed(); // true
match (g.to) {
null => ...
Color => ...
}Exhaustive pattern matching
match on enums requires coverage of all cases:
match (someColor) {
Color.Red => {}
Color.Green => {}
// error: Color.Blue is missing
}Alternatively, use else to handle remaining values:
match (someColor) {
Color.Red => {}
else => {}
}Operator == compares values directly:
if (someColor == Color.Red) {}
else {}Integer representation
At the TVM level, every enum is represented as int. Casting between the enum and int is allowed:
Color.Blue as intevaluates to2;2 as Colorevaluates toColor.Blue.
Operator as can produce invalid values, for example 100 as Color. In this case, operator == returns false, and an exhaustive match throws exception 5.
During deserialization with fromCell(), the compiler validates that encoded integers correspond to valid enum values.
Enums are assignable to integers
Enums are distinct types, but enum values can be assigned to int (and intN) variables without an explicit as cast:
var x: int = Color.Red;
var y: int32 = VmExitCode.OutOfGasError;This is most useful for enums that represent TVM exit codes, operation ids, modes, and other numeric constants.
Usage in throw and assert
Enums are allowed in throw and assert:
enum Err {
InvalidId = 0x100
TooHighId
}
fun validate(id: int) {
assert (id < 1000) throw Err.TooHighId; // excno = 257
}Stack layout and serialization
Every enum is backed by TVM INT and serialized as (u)intN, where N is:
- specified manually, for example:
enum Role: int8 { ... }; - or calculated automatically to fit all values.
Last updated on