Я пытаюсь написать контейнер для объектов типа T
, который обеспечивает доступ к хранимым объектам &T
(я хочу избежать копирования). Так как контейнер только когда-либо растет в течение его срока службы, срок службы возвращаемых ссылок &T
должен быть таким же, как для контейнера.Есть ли идиоматический способ сохранить ссылки на элементы постоянно растущего контейнера?
Ближайший я до сих пор должен был использовать Box<T>
объектов внутри контейнера и использовать Box<T>.as_ref()
, чтобы возвращать ссылки на эти объекты. Затем, однако, я столкнулся с такой же проблемой, как в этом примере минимальный:
fn main() {
let mut v = vec![Box::new(1)]; // line 1
let x = v[0].as_ref(); // line 2: immutable borrow occurs here
println!("x = {:?}", x); // line 3
v.push(Box::new(2)); // line 4: mutable borrow occurs here -> error
println!("x = {:?}", x); // line 5
}
Я понимаю, что это было бы несостоятельным использовать x
в строке 5, если он был удален из v
при изменяемом заема. Но это не тот случай, и это никогда не будет для моего контейнера. Если нет надежного способа выразить это в Rust, как я могу «восстановить» пример (без копирования x
)?
Я знаю потенциального перераспределения утрачивает ссылки на элементы Vec. Вот почему я использовал Vec>: ссылки на Box неустойчивы, но ссылки на T стабильны, не так ли? В конце концов, Vec > не требует, чтобы Box был клонированным, поэтому он не может аннулировать ссылки на T. –
chs
В этот момент вам действительно нужно: «Rc», потому что это буквально определение ссылки общего пользования в Rust –
Vec является (единственным) владельцем указателя, поэтому подсчет ссылок - это не то, что я хочу , Это отлично подходит для ссылок, которые будут признаны недействительными, как только закончится срок существования Vec. (Я соглашаюсь, что подсчет ссылок позволит избежать всей проблемы с владением, но я хочу, чтобы ссылки были максимально легкими по соображениям производительности.) – chs