RustIntermedio6 nov 2025

El truco del Deref: ¡No es un billete de tren gratis para tu String!

snippet.rust
struct Wrapper<T>(T);

impl<T> std::ops::Deref for Wrapper<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}

fn main() {
    let my_string_wrapper = Wrapper(String::from("¡Hola, Rustacean!"));
    let inner_string: String = my_string_wrapper;
    println!("{}", inner_string);
}

¿Qué crees que imprime?

Salida Esperada

¡Hola, Rustacean!

⚠️ Salida Real

error[E0308]: mismatched types
 --> src/main.rs:13:30
  |
13 |     let inner_string: String = my_string_wrapper;
   |                                ^^^^^^^^^^^^^^^^^ expected struct `String`, found struct `Wrapper`
   |
   = note: expected type `String`
              found type `Wrapper<String>`

¿Por qué pasa esto?

¡Ah, el **trait `Deref`**! Es como esa tarjeta VIP que te permite entrar a la sección "solo para miembros" de un club (tu tipo envuelto). Pero ojo, te da acceso para *mirar* y *usar* los métodos del tipo interno a través de una **referencia**, ¡no para **sacarlo y llevártelo a casa**! 😜 Cuando defines `impl Deref for Wrapper<T>`, le dices a Rust: "Oye, cuando alguien tenga una `&Wrapper<T>`, puede *actuar* como si tuviera una `&T`". Es una **coerción de referencia** muy útil. Pero al intentar `let inner_string: String = my_string_wrapper;`, no estás pidiendo una referencia. ¡Estás pidiendo que el `String` interno **se mueva** fuera del `Wrapper`! Y `Deref` no concede ese tipo de "mudanza". Para eso necesitarías implementar **`From` o `Into`**, o simplemente acceder al campo directamente (`my_string_wrapper.0`). `Deref` es un "mirador", no un "empacador de mudanzas" para tus valores. ¡El compilador, como buen portero, te niega la entrada! 🚫

Conceptos relacionados

Derefownershipmoves