Avatar ·

¿Qué significa la palabra clave `dyn` en los tipos de Rust?

¡Hola! Empecé a aprender Rust y me encontré con algo extraño. En algunos ejemplos veo `Box`, y en otros solo `Box` o `&dyn Trait`. Estoy tratando de entender qué hace exactamente la palabra clave `dyn`. Por ejemplo, tengo este código: ```rust trait Animal { fn speak(&self); } struct Dog; impl Animal for Dog { fn speak(&self) { println!("¡Guau!"); } } fn main() { let pet: Box = Box::new(Dog); pet.speak(); } ``` Si quito `dyn` y escribo solo `Box`, el compilador da un error: "the trait `Animal` cannot be made into an object". Pero no entiendo por qué ocurre esto, y qué significa realmente `dyn`. ¿Es algún tipo especial? ¿O un modificador? ¿Cuándo debo usarlo y cuándo no? Explíquenlo, por favor, como para un principiante. ¡Gracias de antemano! <<>>

¿Qué es dyn y para qué sirve?

La palabra clave dyn en Rust es un marcador sintáctico que indica que se está utilizando despacho dinámico (dynamic dispatch) para un trait. En otras palabras, le dice al compilador que el tipo concreto se determinará en tiempo de ejecución, no en tiempo de compilación. Esto es necesario cuando trabajas con trait objects, como `Box` o `&dyn Trait`, porque el tamaño del tipo subyacente no se conoce de antemano. Antes de Rust 2018, se podía escribir `Box` sin `dyn`, pero esto causaba ambigüedad: ¿era un trait object o un tipo genérico? Desde Rust 2018, `dyn` es obligatorio para trait objects, y escribir `Box` sin `dyn` da un error porque el compilador espera un tipo concreto, no un trait. En tu ejemplo, `Animal` es un trait, no un tipo concreto. Al usar `Box`, estás creando un trait object que puede contener cualquier tipo que implemente `Animal`, pero el tamaño se maneja mediante un puntero (fat pointer) que incluye un vtable para el despacho dinámico. Sin `dyn`, el compilador no sabe si quieres un tipo genérico o un trait object, por lo que requiere `dyn` para desambiguar. Usa `dyn` cuando necesites polimorfismo en tiempo de ejecución, por ejemplo, cuando tengas una colección de diferentes tipos que implementan el mismo trait. No lo uses cuando puedas usar genéricos con monomorfización (despacho estático), ya que es más eficiente.