Skip to content

Structs and Enums

A struct declaration defines a named structure type with typed fields. It appears at the top level of a .slint file, alongside components, globals, and enums; it cannot be declared inside a component:

export struct Player {
name: string,
score: int,
}
slint

Fields are separated by commas. A trailing comma after the last field is permitted. A ; between fields is a compile error; the compiler tells you to use , instead. An empty struct { } is allowed.

A struct may be prefixed with one or more @rust-attr(...) attributes and may be exported. Declaring a struct whose name matches an already-defined type replaces the earlier type and emits a warning.

A struct value is written as a struct literal that initializes fields by name: { field1: expression1, field2: expression2 }. A trailing comma after the last member is permitted. A field is read with the . operator: player.name.

export struct Player {
name: string,
score: int,
}
export component Example {
in-out property<Player> player: { name: "Foo", score: 100 };
out property<string> who: player.name;
}
slint

A struct literal need not list every field. When a literal is assigned where a named struct is expected, each member is resolved against the type of the matching field, omitted fields take their default value, and members that don’t name a field of the target struct are ignored.

The default value of a struct has every field set to its own default value, unless the field declares its own.

= expression after a field’s type declares a default value for that field:

export struct Player {
name: string = "unknown",
score: int = 100,
}
export component Example {
// player.name is "Foo", player.score is 100
in-out property<Player> player: { name: "Foo" };
}
slint

The expression must be a compile-time constant. It may combine literals, casts, and operators, but referencing a property, an element, or any runtime value is a compile error.

The default applies whenever an instance of the struct is created without a value for the field: in struct literals that omit the field, in properties of that struct type that are never set, and when the struct is constructed from native code (Rust Player::default(), C++ Player{}, JavaScript new ui.Player(), Python ui.Player()).

Field default values are only supported in named struct declarations. Writing = expression in an anonymous struct type is a compile error.

{ identifier1: type1, identifier2: type2 } is an anonymous struct type. It behaves like a named struct without a name:

export component Example {
in-out property<{name: string, score: int}> player: { name: "Foo", score: 100 };
in-out property<{a: int, }> foo: { a: 3 };
}
slint

Two anonymous struct types with the same fields are the same type. A named struct is only ever equal to itself: it is not interchangeable with an anonymous struct of identical fields.

An enum declaration defines an enumeration. Like a struct, it appears at the top level and may be exported and prefixed with @rust-attr(...):

export enum CardSuit { clubs, diamonds, hearts, spade }
export component Example {
in-out property<CardSuit> card: spade;
out property<bool> is-clubs: card == CardSuit.clubs;
}
slint

Values are separated by commas, with an optional trailing comma. An enum must have at least one value; an empty enum is a compile error. A value may not have the same name as the enum, and the values must be distinct (names that differ only in -/_ or case collide, since they map to the same identifier).

An enum value is referenced with the enum name and the value name separated by a dot: CardSuit.spade.

The enum name may be omitted wherever a value of that enum type is the expected type: in a binding, a struct field, an array element, a function or callback argument, and a return value.

export enum CardSuit { clubs, diamonds, hearts, spade }
export struct Card { suit: CardSuit, value: int }
export component Example {
// in a struct field and an array element
out property<Card> card: { suit: hearts, value: 10 };
out property<[CardSuit]> deck: [clubs, diamonds, hearts, spade];
pure function is-red(suit: CardSuit) -> bool {
return suit == hearts || suit == diamonds;
}
// as a function argument
out property<bool> spade-is-red: is-red(spade);
}
slint

In a comparison the name may be omitted only on the right-hand side, which takes the type of the left: card.suit == hearts works, but hearts == card.suit does not, because the left operand has no expected type.

The default value of an enum type is its first value.


© 2026 SixtyFPS GmbH