#rust
#Ржавчина
Вопрос:
Это минимальный пример. У меня есть функция foo
, которая берет ссылку на вектор и возвращает совершенно новый вектор. Затем есть еще одна функция bar
, которая итеративно вызывает foo
и обновляет свое состояние. Но я не могу заставить его скомпилироваться.
fn foo(input: amp;Veclt;i32gt;) -gt; Veclt;i32gt; { let len = input.len(); return input[0..len-1].to_vec(); } fn bar() { let input = vec![1,2,3,4,5]; let mut out = amp;input; for _ in 0..2 { out = foo(out); } }
Выдает эту ошибку:
78 | out = foo(out); | ^^^^^^^^ | | | expected `amp;Veclt;i32gt;`, found struct `Vec` | help: consider borrowing here: `amp;foo(out)`
Так что это имеет смысл, так out
как имеет несоответствующий тип amp;Veclt;i32gt;
. Теперь, если я добавлю амперсанд перед foo(out)
вызовом, то получу другую ошибку:
78 | out = amp;foo(out); | ^^^^---^- temporary value is freed at the end of this statement | | | | | borrow later used here | creates a temporary which is freed while still in use
Как правильно это исправить?
Ответ №1:
Чистый способ, если это возможно, состоит в том, чтобы последовательно придерживаться фактического значения вместо ссылки:
fn bar() { let input = vec![1,2,3,4,5]; let mut out = input; for _ in 0..2 { out = foo(amp;out); } }
или, что эквивалентно,
fn bar() { let input = vec![1,2,3,4,5]; let out = (0..2).fold(input, |prev, _| foo(amp;prev)); }
Но если вам нужно будет продолжать использовать input
позже, то вам придется найти какой-то другой способ сделать возвращаемое значение foo
жить дольше, чем цикл, например
fn bar() { let input = vec![1,2,3,4,5]; let mut out_storage; let mut out = amp;input; for _ in 0..2 { out_storage = foo(out); out = amp;out_storage; } }