所以我需要引用刚刚推送到 Vec 的东西,例如
my_vec.push(foo);
Somelib::do_something_with(&my_vec, &foo); // borrow checker says hi
现在,这有效了:
Somelib::do_something_with(&my_vec, &my_vec.last().unwrap());
但是就是这样吗?或者说正确的做法是什么?
当您按值将元素推入 Vec 时,您正在移动该值。这将使对该值的任何现有引用无效。借用检查器是正确的。
如果您需要将值移入 Vec,您别无选择,只能以某种方式从 Vec 获取对该项目的引用。否则,保留引用的 Vec 而不是值的 Vec,问题就会消失。
如果您需要在多个地方执行此操作,我建议为此实现一个扩展特征。这样,逻辑就只存在于一个地方,并且您不必将
.unwrap()
或 .expect()
放在很多地方。
例如:
pub trait VecExt<T> {
fn push_returning_ref(&mut self, item: T) -> &T;
}
impl<T> VecExt<T> for Vec<T> {
fn push_returning_ref(&mut self, item: T) -> &T {
self.push(item);
self.last().expect("vec must have item after push")
}
}
fn example_usage() {
let item: String = String::from("hello");
let mut list: Vec<String> = Vec::new();
let ref_to_item: &str = list.push_returning_ref(item);
}