Trait objects en Rust
Un Vec de Box<dyn Trait> guarda tipos concretos distintos tras una sola interfaz.
trait Check {
fn name(&self) -> &str;
fn passes(&self, text: &str) -> bool;
}
struct MinLength(usize);
struct NoSpaces;
impl Check for MinLength {
fn name(&self) -> &str {
"min length"
}
fn passes(&self, text: &str) -> bool {
text.len() >= self.0
}
}
impl Check for NoSpaces {
fn name(&self) -> &str {
"no spaces"
}
fn passes(&self, text: &str) -> bool {
!text.contains(' ')
}
}
fn main() {
let checks: Vec<Box<dyn Check>> =
vec![Box::new(MinLength(3)), Box::new(NoSpaces)];
for candidate in ["ada", "ada lovelace", "x"] {
let failed: Vec<&str> = checks
.iter()
.filter(|c| !c.passes(candidate))
.map(|c| c.name())
.collect();
println!("{candidate:?} failed {:?}", failed);
}
}
Cómo funciona
dyn Traitdespacha en tiempo de ejecución vía una vtable.- El Box es lo que uniforma los tamaños.
- Los genéricos obligarían a que todo elemento fuera del mismo tipo.
Palabras clave y builtins usados aquí
BoxVecbooldynfnforimplinletselfstrstructtraitusize
El intento, en números
- Líneas
- 39
- Caracteres a escribir
- 682
- Tokens
- 234
- Ritmo de tres estrellas
- 110 tpm
Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 128 segundos.
Paso 1 de 3 en Despacho dinámico; paso 16 de 19 en Traits y genéricos.