2021年4月24日星期六

Variable is moved to closure even when it is not executed

I have a function that can return only one error, so I want to create it once and return that instance if needed.

Here's an example to demonstrate:

fn foo() -> Result<(), String> {      let err = String::from("error message");      let a = function_that_returns_an_option().ok_or_else(|| err)?;      let b = function_that_returns_another_option().ok_or_else(|| err)?;      // ...do something with a and b...      Ok(())  }  

Which results in the following compilation error:

error[E0382]: use of moved value: `err`    --> src/main.rs:12:61     |  10 |     let err = String::from("error message");     |         --- move occurs because `err` has type `String`, which does not implement the `Copy` trait  11 |     let a = function_that_returns_an_option().ok_or_else(|| err)?;     |                                                           -- --- variable moved due to use in closure     |                                                           |     |                                                           value moved into closure here  12 |     let b = function_that_returns_another_option().ok_or_else(|| err)?;     |                                                                ^^ --- use occurs due to use in closure     |                                                                |     |                                                                value used here after move  

I thought the move happens lazily, but if I understand correctly, err is moved to the first closure even if the closure is not executed and therefore it cannot be used in the second closure (or the compiler does not know that and rejects it just to be safe?). I can replace the err in the closures with err.clone(), but that defeats the purpose a little bit. Is there maybe another more "idiomatic" way to do that?

https://stackoverflow.com/questions/67248854/variable-is-moved-to-closure-even-when-it-is-not-executed April 25, 2021 at 09:05AM

没有评论:

发表评论