Я недавно столкнулся с сообщением о проверке заимствований, которое раньше никогда не видел, и которое я пытаюсь понять. Вот код для его воспроизведения (упрощенный, реальный пример был более сложным) - детская площадка :
fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
let dest = if which { &mut v1 } else { &mut v2 };
dest.push(1);
}
Не удается скомпилировать со следующей ошибкой:
error[E0623]: lifetime mismatch
--> src/main.rs:2:44
|
1 | fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
| ------------ ------------ these two types are declared with different lifetimes...
2 | let dest = if which { &mut v1 } else { &mut v2 };
| ^^^^^^^ ...but data from `v2` flows into `v1` here
... а затем еще один о данных, поступающих из v1
в v2
.
Мой вопрос: что означает эта ошибка? Что такое поток данных и как он происходит между двумя переменными, учитывая, что код передает только Copy
данные одной из них?
Если я следую за компилятором и форсирую время жизни v1
и Для соответствия v2
функция компилирует ( площадка ):
fn foo<'a>(mut v1: &'a mut Vec<u8>, mut v2: &'a mut Vec<u8>, which: bool) {
let dest = if which { &mut v1 } else { &mut v2 };
dest.push(1);
}
Однако при дальнейшей проверке выяснилось, что исходный код был излишне сложным, оставшимся после того, как v1
и v2
были фактическими Vec
с, а не ссылками. Более простой и естественный вариант - установить dest
не на &mut v1
и &mut v2
, а на более простые v1
и v2
, которые являются ссылками для начала. И это тоже компилируется ( детская площадка ):
fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
let dest = if which { v1 } else { v2 };
dest.push(1);
}
В этой, казалось бы, эквивалентной формулировке время жизни совпадений v1
и v2
больше не требуется.