Enum esperado `std :: result :: Result`, encontrado` () `cuando se usa el bucle for

Nov 26 2020

Estoy jugando con uno de los ejemplos del proyecto de sintetizador de texturas :

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    //create a new session
    let texsynth = ts::Session::builder()
        //load a single example image
        .add_example(&"imgs/1.jpg")
        .build()?;

    //generate an image
    let generated = texsynth.run(None);

    //save the image to the disk
    generated.save("out/01.jpg")
}

Me gustaría repetir esto tres veces usando un forbucle. Así fue como pensé que podría hacerlo:

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    for i in 0..3 {
        let texsynth = ts::Session::builder()
            //load a single example image
            .add_example(&"imgs/1.jpg")
            .build()?;

        //generate an image
        let generated = texsynth.run(None);

        //save the image to the disk
        let index: String = i.to_string();
        let outputPath = ["out/", &index, ".jpg"].concat();
        generated.save(outputPath );
    };
}

Sin embargo, esto me da el error:

fn main() -> Result<(), ts::Error> {
  |    ----      ^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `()`        
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression

¿Parece que la función principal arroja un error porque no obtiene un resultado del tipo que desea? ¿Cómo puedo arreglar esto?

Respuestas

4 Jmb Nov 26 2020 at 14:42

La mainfunción se define como fn main() -> Result<(), ts::Error>, lo que significa que debe devolver un valor de tipo Result<(), ts::Error>. En el código original, esto se logra mediante la última línea:

generated.save("out/01.jpg")  // Note the absence of semicolon here

porque generated.savedevuelve un valor del tipo correcto (la returnpalabra clave es opcional para la última expresión de una función en Rust, siempre que no haya un punto y coma después de la expresión).

Para solucionar su problema, deberá asegurarse de que maindevuelva un valor del tipo correcto. Esto requiere dos cambios:

  • Si una llamada a generated.savedevuelve un error, debe propagar el error. Esto lo logra el ?operador de sufijo.
  • Si el ciclo finaliza con éxito, debería devolver un valor que signifique que todo está bien. Este valor es Ok(()).

Código completo:

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    //create a new session

    for i in 1..3{
        let texsynth = ts::Session::builder()
            //load a single example image
            .add_example(&"imgs/1.jpg")
            .build()?;

        //generate an image
        let generated = texsynth.run(None);

        //save the image to the disk
        let index: String = i.to_string();
        let outputPath = ["out/", &index, ".jpg"].concat();
        generated.save(outputPath)?;
    };

    Ok(())
}