Skip to content

Interfaces and dyn

Use case: one algorithm, many shapes (static)

Section titled “Use case: one algorithm, many shapes (static)”
interface Shape {
fn area(self) -> int
fn describe(self) -> int {
return self.area()
}
}
struct Circle {
radius: int
fn area(self) -> int {
return 3 * self.radius * self.radius
}
}
fn report(s: Shape) -> int {
return s.describe()
}
fn main(caps: Caps) -> int {
return report(Circle { radius: 2 })
}

Static interface parameters are specialized per call site (zero vtable cost).

When one Array must hold different implementors:

// fragment-only
fn total_area(shapes: Array<dyn Shape>) -> int {
var sum = 0
for s in shapes {
sum = sum + s.area()
}
return sum
}
fn main(caps: Caps) -> int {
var shapes = [
Circle { radius: 2 } as dyn Shape,
Square { side: 3 } as dyn Shape
]
print total_area(shapes)
return 0
}

dyn makes the indirection visible in the type — consistent with “the signature tells you everything.”

Interface methods may include a body (free for all implementors that do not override the idea — here describe defaults to calling area).