Traits & Extend
trait describes capabilities a type must provide. Use traits to constrain generics and organize shared APIs. A trait is not a normal value type.
Defining Traits
Section titled “Defining Traits”Empty traits can be declared with a semicolon:
Traits with required methods use a body:
Requirements with a self parameter use the current value as the receiver. Requirements without
self are associated functions on the implementing type.
Hashable feeds a value into any concrete Hasher; it does not choose or return a hash algorithm
itself. Hasher also provides write overloads with default implementations for primitive values.
Dynamic Trait Values
Section titled “Dynamic Trait Values”Dynamic trait values use compiler-provided companion types on every trait:
Any and Receiver are reserved companion type names on traits; they are not user-defined
associated types. Writer.Any& is a borrowed dynamic view of any value whose concrete type implements
Writer. Construct it with Writer$.ref(value):
The construction requires typeof(file): Writer; it is not an unchecked cast and it does not move
file. Use Writer$.new(value) when the dynamic trait value should own the receiver:
An owning dynamic trait value stores the receiver and drops it when the Writer.Any^ is dropped.
The compiler keeps a method table for the concrete implementation internally; that table type is not
a public type user source can name. Writer.Receiver is the erased receiver used by instance-method slots:
Writer.Any& conceptually stores a Writer.Receiver plus the matching method table. Calls through
Writer.Any& dispatch through that table:
Passing a trait method pointer uses the unbound vtable slot form. Receiver methods include the erased receiver as their first parameter, while associated functions keep their declared parameter list:
The current implementation supports dynamic dispatch for reference receiver methods, method slot access, and dropping owning dynamic trait values.
Implementing in a Type Body
Section titled “Implementing in a Type Body”Types can list traits in their declaration and provide matching methods:
extend
Section titled “extend”extend adds methods or a trait implementation after the type declaration:
extend Type: Trait { ... } provides that trait’s required methods for the type. Generic
extensions, @where type-shape matching, module visibility, and public extend are covered in
Extensions.
Associated Types
Section titled “Associated Types”Associated types can have bounds:
Implementations bind associated types:
extend can bind them too:
Use a qualified associated type path when multiple traits expose the same associated name:
Trait Bounds
Section titled “Trait Bounds”Associated type binding:
Projected equality:
Built-in Traits
Section titled “Built-in Traits”The prelude provides common trait and bound names such as:
NumericMutableHashableEquatableFromStringLiteralIterator/SequenceSubscriptGet/SubscriptSet
Subscript traits can model value[index]: