Consider the following code:
fn print_or(opt: Option<()>, tail: Vec<i32>) -> Vec<i32> {
opt.map_or(tail, |_| {
println!("{:?}", tail);
tail
})
}
The error message says that:
error[E0382]: use of moved value: `tail`
--> src/lib.rs:2:22
|
1 | fn print_or(opt: Option<()>, tail: Vec<i32>) -> Vec<i32> {
| ---- move occurs because `tail` has type `Vec<i32>`, which does not implement the `Copy` trait
2 | opt.map_or(tail, |_| {
| ---- ^^^ value used here after move
| |
| value moved here
3 | println!("{:?}", tail);
4 | tail
| ---- use occurs due to use in closure
|
help: consider cloning the value if the performance cost is acceptable
|
2 | opt.map_or(tail.clone(), |_| {
| ++++++++
And it's clear since I use owned Vec<i32>
type here. But the problem is that it's pretty obvious that it cannot be used after move since Option
cannot be Some
and None
at the same time. Is there a way to overcome the problem without clone
or Rc
?
Rust doesn't really have a way to say that only one argument of a function will be used, but it does know that only one branch of a control flow statement will run, so you can use match
:
match opt {
None => tail,
Some(()) => {
println!("{:?}", tail);
tail
}
}
Similarly, you can use if let
:
if let Some(()) = opt {
println!("{:?}", tail);
tail
} else {
tail
}
And in this case, you can just check if opt
is Some
since both branches end in the same thing:
if opt.is_some() {
println!("{:?}", tail);
}
tail