Structs & traits
22 steps in 5 sets of Mojo.
A struct is how you name a type in Mojo. It has no hidden header, no vtable, and no allocation you did not ask for — the fields you declare are the memory the value occupies, and the compiler lays them out flat. That is what people mean when they call Mojo structs zero-overhead types.
The heart of it is value semantics. Assigning a struct copies it rather than aliasing it, and every argument spells out its intent: read-only by default, mut when the callee edits the caller's value, var plus a trailing caret when ownership moves. Traits then layer shared behavior on top without giving any of that up — a generic function bound by a trait is compiled fresh for each type it meets, so the abstraction disappears before the program runs.
This tour builds one up from bare fields, follows a value through copies and transfers, teaches a struct the operators it deserves, and finishes with traits and the generic code they unlock.
A first struct
- A struct and its fieldsA struct is a named bundle of fields with a fixed layout the compiler knows exactly.
- Methods on a structMethods are functions that take
self, so they can read the fields alongside them. - Fieldwise initialization
@fieldwise_initwrites the constructor for you, one argument per field in order. - Structs holding structsA struct field can be another struct, and the whole thing stays one flat value.
- Static methods as constructors
@staticmethodgives a struct named constructors that read better than raw arguments.
Value semantics
- Assignment copies the valueMojo structs are values, so assigning one makes an independent copy, not an alias.
- Transferring ownership
Ticketis not copyable, so passing it along means handing over ownership with^. - Mutating with mut
mutmarks an argument the callee may change in place, edits landing on the caller's value. - Read-only by defaultArguments are read-only unless you say otherwise, which costs nothing at runtime.
- Copy and destroy hooksA struct can define what copying and destruction mean for it.
Operators
- Adding with __add__Implement
__add__and the+operator starts working on your own type. - Equality and ordering
__eq__and__lt__teach a struct how to answer==and<. - Subscripting a struct
__getitem__and__setitem__put square-bracket syntax on your own container. - Truthiness with __bool__
__bool__decides what your struct means inside anif. - Printable structsConform to
Writableand your struct prints itself, no formatting helper required.
Traits
- Declaring a traitA trait names the methods a type must supply, without saying how.
- Two structs, one traitUnrelated types can satisfy the same trait, each in its own way.
- Generic functions over traitsA trait bound lets one function serve every conforming type, compiled fresh for each.
- Combining trait bounds
&joins trait bounds, demanding a type satisfy every one of them. - Sorting your own structConform to
Comparableand the standardsortwill order your values.
Encore
- Bank ledgerAn account struct that guards its own balance and keeps a running history.
- Shape galleryOne trait, three shapes, and a single generic function that tabulates them all.