# Enums (https://docs-dmpho5eos-ton-core-docs.vercel.app/llms/tolk/types/enums/content.md)



Tolk supports enums, similar to TypeScript and C++ enums.

In the [TVM](/llms/tvm/overview/content.md), all enums are represented as integers. At the compiler level, an enum is a distinct type.

```tolk
// will be 0 1 2
enum Color {
    Red
    Green
    Blue
}
```

## Enum members [#enum-members]

Values can be specified manually. Otherwise, they are auto-calculated as `+1`.

```tolk
enum Mode {
    Foo = 256,
    Bar,        // implicitly 257
}
```

## Enum types [#enum-types]

Enums are distinct types, not integers. `Color.Red` has type `Color`, not `int`, although it holds the value `0` at runtime.

```tolk
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.

```tolk
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 [#exhaustive-pattern-matching]

[`match`](/llms/languages/tolk/syntax/pattern-matching/content.md) on enums requires coverage of all cases:

```tolk
match (someColor) {
    Color.Red => {}
    Color.Green => {}
    // error: Color.Blue is missing
}
```

Alternatively, use `else` to handle remaining values:

```tolk
match (someColor) {
    Color.Red => {}
    else => {}
}
```

Operator `==` compares values directly:

```tolk
if (someColor == Color.Red) {}
else {}
```

## Integer representation [#integer-representation]

At the TVM level, every enum is represented as `int`. Casting between the enum and `int` is allowed:

* `Color.Blue as int` evaluates to `2`;
* `2 as Color` evaluates to `Color.Blue`.

<Callout type="caution">
  Operator `as` can produce invalid values, for example `100 as Color`. In this case, operator `==` returns `false`, and an exhaustive `match` throws exception [5](/llms/tvm/exit-codes/content.md).
</Callout>

During deserialization with `fromCell()`, the compiler validates that encoded integers correspond to valid enum values.

### Enums are assignable to integers [#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:

```tolk
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` [#usage-in-throw-and-assert]

Enums are allowed in `throw` and `assert`:

```tolk
enum Err {
    InvalidId = 0x100
    TooHighId
}

fun validate(id: int) {
    assert (id < 1000) throw Err.TooHighId;  // excno = 257
}
```

## Stack layout and serialization [#stack-layout-and-serialization]

Every enum is [backed by TVM](/llms/languages/tolk/types/overall-tvm-stack/content.md) `INT` and [serialized](/llms/languages/tolk/types/overall-serialization/content.md) as `(u)intN`, where `N` is:

* specified manually, for example: `enum Role: int8 { ... }`;
* or calculated automatically to fit all values.
