Traits
Define shared behavior across types with trait declarations and implementations.
Traits
Traits define shared interfaces that multiple types can implement. They are Sounio’s mechanism for bounded polymorphism — a function can require that its type parameter implements a specific trait.
Declaring a trait
trait Printable {
fn to_string(self) -> str
}
trait Measurable {
fn magnitude(self) -> f64
}
Implementing a trait
struct Point { x: f64, y: f64 }
impl Printable for Point {
fn to_string(self) -> str {
format("({}, {})", self.x, self.y)
}
}
impl Measurable for Point {
fn magnitude(self) -> f64 {
sqrt(self.x * self.x + self.y * self.y)
}
}
Trait bounds
Use trait bounds to constrain generic type parameters:
fn display<T: Printable>(value: T) with IO {
println(value.to_string())
}
fn compare_magnitudes<T: Measurable>(a: T, b: T) -> bool {
a.magnitude() > b.magnitude()
}
Where trait checking lives
Trait resolution is implemented in self-hosted/check/traits.sio. The checker verifies that:
- Every
implblock provides all required methods. - Method signatures in the
implmatch the trait declaration. - Trait bounds at call sites are satisfied by the concrete type.
Current status
Trait declarations, implementations, and simple bounds are supported by the current parser and type checker. More advanced features (associated types, default methods, trait inheritance) are tracked in the feature status page.