07 · Traits
A trait defines a set of method signatures that any type can implement. Traits are the primary polymorphism mechanism in Sigil — they replace virtual dispatch tables in most systems languages while remaining zero-cost. A function that accepts impl Area works with any type that implements Area, resolved at compile time.
trait Area { fn area(&self) -> f32; fn perimeter(&self) -> f32;}
struct Circle { radius: f32 }struct Rect { width: f32, height: f32 }
impl Area for Circle { fn area(&self) -> f32 { 3.14159 * self.radius * self.radius } fn perimeter(&self) -> f32 { 2.0 * 3.14159 * self.radius }}
impl Area for Rect { fn area(&self) -> f32 { self.width * self.height } fn perimeter(&self) -> f32 { 2.0 * (self.width + self.height) }}
// Generic over anything that implements Area.fn print_stats(shape: &impl Area) !io { println!("area = {:.2}", shape.area()); println!("perimeter = {:.2}", shape.perimeter());}
fn main() !io { let c = Circle { radius: 5.0 }; let r = Rect { width: 4.0, height: 6.0 };
println!("-- Circle --"); print_stats(&c); println!("-- Rect --"); print_stats(&r);}Output
Section titled “Output”-- Circle --area = 78.54perimeter = 31.42-- Rect --area = 24.00perimeter = 20.00What the compiler sees
Section titled “What the compiler sees”impl Area in a parameter position is syntactic sugar for <T: Area>(shape: &T) — the compiler monomorphizes print_stats for each concrete type, so dispatch is a direct call with no vtable. Implementing a trait for a type that doesn’t satisfy all method signatures is a compile error; there is no partial implementation.
Next → 08 · Generics