试图编译:
fn main() {
let mut vec = vec![1, 2, 3];
let four: &mut u32 = borrow_or_add(&mut vec, 4);
}
fn borrow_or_add(vec: &mut Vec<u32>, val: u32) -> &mut u32 {
vec.iter_mut().find(|v| **v == val).unwrap_or({
vec.push(val);
vec.last_mut().unwrap()
})
}
Run Code Online (Sandbox Code Playgroud)
...给出以下结果:
q.rs:8:9: 8:12 error: cannot borrow `*vec` as mutable more than once at a time
q.rs:8 vec.push(val);
^~~
q.rs:7:5: 7:8 note: previous borrow of `*vec` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*vec` until the borrow ends
q.rs:7 vec.iter_mut().find(|v| **v == val).unwrap_or({
^~~
q.rs:12:2: 12:2 note: previous borrow ends here
q.rs:6 fn borrow_or_add(vec: &mut Vec<u32>, val: u32) -> &mut u32 {
...
q.rs:12 }
^
q.rs:10:9: 10:12 error: cannot borrow `*vec` as mutable more than once at a time
q.rs:10 vec.last_mut().unwrap()
^~~
q.rs:7:5: 7:8 note: previous borrow of `*vec` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*vec` until the borrow ends
q.rs:7 vec.iter_mut().find(|v| **v == val).unwrap_or({
^~~
q.rs:12:2: 12:2 note: previous borrow ends here
q.rs:6 fn borrow_or_add(vec: &mut Vec<u32>, val: u32) -> &mut u32 {
...
q.rs:12 }
^
q.rs:10:9: 10:12 error: cannot borrow `*vec` as mutable more than once at a time
q.rs:10 vec.last_mut().unwrap()
^~~
q.rs:7:5: 7:8 note: previous borrow of `*vec` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*vec` until the borrow ends
q.rs:7 vec.iter_mut().find(|v| **v == val).unwrap_or({
^~~
q.rs:12:2: 12:2 note: previous borrow ends here
q.rs:6 fn borrow_or_add(vec: &mut Vec<u32>, val: u32) -> &mut u32 {
...
q.rs:12 }
^
Run Code Online (Sandbox Code Playgroud)
据我所知,身体unwrap_or()不能参考上面提到的借用vec,为什么不从范围中删除呢?有没有一种优雅的方式来实现这个功能?我实际上找不到一种方法来成功地做到这一点,而不使用两个传递和一个bool(即contains()).
小智 7
借款至少在整个陈述中是有效的.不幸的是,通常的解决方法是将它Option拉出到一个单独的语句中也无济于事,因为它仍然包含一个可变引用(in Some),它会强制扩展向量的借用.这在使用时似乎是不可避免的find().编译器担心指向Vector存储的指针在某处浮动,并且可能通过推入向量(这可能导致重新分配)而无效.这不仅包括返回的指针,Option还包括可由其中一个函数内部生成的指针.这将是一个非常有效的问题,如果不是因为没有"隐藏"指针而你只是在Option 不是指针的情况下推动.生命周期系统的细微程度不足以捕获这一事实,我没有看到一种简单的方法来修复它或解决它.
你可以做的是position用来找到一个索引:
fn borrow_or_add(vec: &mut Vec<u32>, val: u32) -> &mut u32 {
match vec.iter().position(|&v| v == val) {
Some(i) => &mut vec[i],
None => {
vec.push(val);
vec.last_mut().unwrap()
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,向量中的索引基本上是美化指针.如果向量发生变化,它们可以开始引用错误的元素,尽管它们不能在重新分配时变得悬空,而无效的索引(大于最大的有效索引)将导致恐慌而不是内存不安全.仍然,从中获取索引position然后使用索引进行索引只是正确的,因为矢量在其间没有(基本上)修改.
| 归档时间: |
|
| 查看次数: |
362 次 |
| 最近记录: |