Crash al convertir un String a una referencia de cadena (&str) en Rust

Publicado por Brisa
hace 11 meses

Hola a todos,

Estoy trabajando en un proyecto en Rust y me he encontrado con un problema al tratar de convertir un String en una referencia de cadena (&str). Aquí está el código relevante:

fn main() {
    let mensaje = String::from("¡Hola mundo!");

    imprimir_mensaje(&mensaje);
}

fn imprimir_mensaje(mensaje: &str) {
    println!("{}", mensaje);
}

Cuando intento compilar este código, obtengo el siguiente error:

error[E0277]: cannot pass `mensaje` to function as a `&str` because it doesn't implement `std::convert::From<&str>`
 -->
  |
7 |     imprimir_mensaje(&mensaje);
  |                      ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `std::string::String`
  |
  = note: required because of the requirements on the impl of `std::convert::Into<&str>` for `&std::string::String`

Entiendo que Rust es bastante estricto con los tipos y esto podría ser un problema de asignación de tipos. ¿Cómo puedo convertir correctamente un String en una referencia de cadena (&str) en Rust? ¿Qué estoy haciendo mal aquí?

¡Gracias de antemano!

Rust String referencia
Respuesta de Gordon Shumway
hace 11 meses

¡Hola Brisa!

El error que estás teniendo es debido a que Rust no está pudiendo inferir de manera automática la conversión del tipo String a &str. Cuando pasas una referencia a un String con &, obtienes una referencia a String, es decir, &String, no a la cadena de caracteres en sí.

La solución es simple. Puedes usar el método .as_str() del objeto String para obtener una vista de tipo &str de la cadena y pasarla a tu función imprimir_mensaje. Tu código debería verse así:

fn main() {
    let mensaje = String::from("¡Hola mundo!");

    imprimir_mensaje(mensaje.as_str());
}

fn imprimir_mensaje(mensaje: &str) {
    println!("{}", mensaje);
}

También, puedes usar el operador de desreferenciación * en combinación con el operador & para obtener una referencia al str directamente, así:

fn main() {
    let mensaje = String::from("¡Hola mundo!");

    imprimir_mensaje(&*mensaje);
}

fn imprimir_mensaje(mensaje: &str) {
    println!("{}", mensaje);
}

Ambas formas son correctas y convertirán una String a &str para que tu función las acepte sin problemas.

Espero que esta explicación te haya sido útil, y ¡mucho éxito con tu proyecto en Rust! No dudes en preguntar si tienes más dudas.