Chr*_*rce 6 rust borrow-checker
我正在尝试编写一个函数,该函数查找返回对 Vec 中现有元素的可变引用,或者如果它不存在则将其插入并返回对新元素的可变引用。
我已经尝试过几次,但借用检查员并不相信。我已将尝试编写的代码简化为下面的示例,该示例给出了相同的错误。
fn mut_find_or_insert<T: PartialEq>(vec: &mut Vec<T>, val: T) -> &mut T {
if let Some(u) = vec.iter_mut().find(|u| **u == val) {
u
} else {
vec.push(val);
vec.last_mut().unwrap()
}
}
Run Code Online (Sandbox Code Playgroud)
Rust 给出了以下编译器错误(通过游乐场链接的完整消息):
error[E0499]: cannot borrow `*vec` as mutable more than once at a time
Run Code Online (Sandbox Code Playgroud)
这似乎应该可以在 Rust 中实现,但是我不清楚如何重新实现它以避免借用检查器错误。
这不能按书面方式工作的原因是由于当前借用检查器的限制。这与NLL 情况 #3match非常相似,在这种情况下,当借用仅在其中一个分支中使用时,编译器对整个语句的借用有些过度热心。使用实验性的“Polonius”借用检查器(可在夜间编译器上使用-Z polonius),您的代码将按原样被接受。
在稳定的编译器中工作,重新设计数据结构可能是一个好主意,正如S\xc3\xa9bastien Renauld\ 的答案也建议的那样,但如果您需要使用Vec,您可以通过以下方式解决它简单地使用索引来结束借用:
fn mut_find_or_insert<T: PartialEq>(vec: &mut Vec<T>, val: T) -> &mut T {\n if let Some(i) = vec.iter().position(|each| *each == val) {\n &mut vec[i]\n } else {\n vec.push(val);\n vec.last_mut().unwrap()\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n这是有效的,因为调用的结果不是引用,因此在调用期间不会保留 的position借用vecif let。
这类似于以下问题,这些问题设法使用循环的早期返回来找到相同的限制:
\n\n| 归档时间: |
|
| 查看次数: |
6910 次 |
| 最近记录: |