В Rust используется разрушающее сопоставление с образцом, что в купе с моделью памяти Rust, иногда, дает очень занятные эффекты. Для примера возьмем структуру
val: int
}
let stack_data = Some(MyStruct{val:42}); // (1)
let own_data = Some(~MyStruct{val:42}); // (2)
И теперь попробуем применить сопоставление с образцом, но не один раз, как это обычно делается, а дважды. Сценарий выглядит не совсем обычно, но это не более чем выжимка из реального кода.
Some(data) => { println!("We have data {:?}", data);}
None => { println!("We don't have data");}
}
match a_data { // (2)
Some(data) => { println!("We have data {:?}", data);}
None => { println!("We don't have data");}
}
Что бы не приводить один и тот же пример дважды, переменная
Данный код при использовании
destructive_match.rs:30 match local_data {
^~~~~~~~~~
destructive_match.rs:27:14: 27:18 note: `local_data#0` moved here because it has type `~MyStruct`, which is moved by default (use `ref` to override)
destructive_match.rs:27 Some(data) => { println!("We have data {:?}", data);}
^~~~
error: aborting due to previous error
Два этих случая хоть и крайне похожи, но имеют “ньюансик”. Стековые объекты в Rust копируются, как следствие в обоих сопоставлениях с образцом
Что делать и как быть? Например, попросить компилятор не передвигать объект
Some(ref data) => { println!("We have data {:?}", data);}
None => { println!("We don't have data");}
}