es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Puedo declarar un valor enum que acepte un String o &str sin necesidad de funciones adicionales?

Tengo un enum con un String:

rust
enum MyLovelyEnum {
Thing(String),
}

Para las pruebas, me gustaría poder pasar un &'static str para evitar repetir MyLovelyEnum::Thing("abc".to_string) una y otra vez.

Encontré que se puede hacer esto de manera limpia con structs que tienen un constructor:

// From: https://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html
struct Person {
    name: String,
}

impl Person {
    fn new<S: Into<String>>(name: S) -> Person {
        Person { name: name.into() }
    }
}

fn main() {
    let person = Person::new("Herman");
    let person = Person::new("Herman".to_string());
}

Sé que puedo usar lifetimes o Cow como se describe en https://stackoverflow.com/questions/44054746/whats-the-best-practice-for-str-string-values-in-rust-enums o puedo hacer mi propia función.

¿Hay algo similar al ejemplo en el artículo del blog para enums? Por ejemplo:


// esto es lo que estoy buscando, pero esta sintaxis específicamente no es correcta
enum MyLovelyEnum {
Thing<S: Into<String>>(S)
}

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, no hay una sintaxis en Rust que permita que se utilicen tipos genéricos en los constructores de enums como el ejemplo que proporcionaste para structs. Sin embargo, hay algunas soluciones alternativas que puedes usar para lograr una funcionalidad similar.

    Una opción es usar el trait From, que permite la conversión de un tipo a otro. Por ejemplo:

    enum MyLovelyEnum {
        Thing(String),
    }
    
    impl From<&'static str> for MyLovelyEnum {
        fn from(s: &'static str) -> Self {
            MyLovelyEnum::Thing(s.to_owned())
        }
    }
    

    Esta implementación permite pasar un &'static str y convertirlo en una variante de MyLovelyEnum utilizando From.

    Otra opción es crear una función auxiliar fuera del enum para evitar repetir la misma lógica de conversión. Por ejemplo:

    enum MyLovelyEnum {
        Thing(String),
    }
    
    fn make_thing<s:></s:><string>>(s: S) -> MyLovelyEnum {
        MyLovelyEnum::Thing(s.into())
    }
    
    fn main() {
        let thing = make_thing("abc");
    }
    

    Esta función recibe un tipo genérico S que puede ser convertido en un String utilizando el trait Into, luego crea una variante MyLovelyEnum::Thing utilizando el String convertido.

    En resumen, si bien no hay una sintaxis incorporada para constructores genéricos en enums, existen soluciones alternativas como estas que pueden lograr una funcionalidad similar.

Comments are closed.