Cotas de Trait
Las cotas de trait (trait bounds) restringen parámetros de tipo genérico para que una función pueda llamar métodos de trait sobre valores de tipo desconocido. La sintaxis <T: TraitName> significa "esta función funciona para cualquier tipo T que implemente TraitName".
Código
// Trait bounds: función genérica que acepta cualquier tipo con Display
trait Display {
fn to_string(self) -> String
}
struct Point {
x: int,
y: int
}
impl Display for Point {
fn to_string(self) -> String {
return "(" + int_to_string(self.x) + ", " + int_to_string(self.y) + ")"
}
}
struct Circle {
radius: int
}
impl Display for Circle {
fn to_string(self) -> String {
return "Circulo{radio=" + int_to_string(self.radius) + "}"
}
}
fn print_it<T: Display>(x: T) -> String {
return x.to_string()
}
fn show_twice<T: Display>(x: T) {
let s: String = x.to_string()
print(s)
print(s)
}
fn main() -> int {
let p: Point = Point { x: 7, y: 2 }
print(print_it<Point>(p))
let c: Circle = Circle { radius: 10 }
print(print_it<Circle>(c))
show_twice<Point>(p)
return 0
}
Salida
(7, 2)
Circulo{radio=10}
(7, 2)
(7, 2)
Explicación
print_it<T: Display> es una función genérica que acepta cualquier tipo T siempre que implemente Display. La cota T: Display le indica al compilador dos cosas: que puede generar una versión especializada para cada tipo concreto usado en el sitio de la llamada (monomorfización), y que garantiza que x.to_string() siempre es una llamada válida dentro del cuerpo de la función.
show_twice demuestra que los genéricos con cota de trait son funciones ordinarias — pueden tener variables locales, llamar al método del trait varias veces y producir cualquier efecto secundario. El compilador produce versiones de código máquina separadas para Point y cualquier otro tipo que le pases, así que no hay sobrecarga de despacho virtual.
En el sitio de la llamada, el argumento de tipo se escribe explícitamente como print_it<Point>(p). Nyx a menudo puede inferir el argumento de tipo, pero ser explícito siempre es válido y a veces resulta más claro al leer el código.