相关疑难解决方法(0)

什么是非词汇生命?

Rust有一个与非词汇生命周期相关的RFC,已被批准在该语言中实现了很长时间.最近,Rust对此功能的支持有了很大改进,并且被认为是完整的.

我的问题是:非词汇生命究竟是什么?

lifetime rust lifetime-scoping

63
推荐指数
1
解决办法
6149
查看次数

从HashMap或Vec返回引用会导致借用超出其所在的范围?

我有一个持久的编译错误,其中Rust抱怨我在尝试可变借用时有一个不可变的借位,但是不可变借用来自另一个范围,而我并没有从中带来任何东西.

我有一些代码检查地图中的值,如果它存在,则返回它,否则它需要以各种方式改变地图.问题是我似乎无法找到让Rust同时执行的方法,即使这两个操作完全分开.

这是一些荒谬的代码,它遵循与我的代码相同的结构并展示了问题:

use std::collections::BTreeMap;

fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
    // extra scope in vain attempt to contain the borrow
    {
        // borrow immutably
        if let Some(key) = map.get(&key) {
            return Some(key);
        }
    }

    // now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed

    map.insert(0, 0); // borrow mutably, which errors
    None
}
Run Code Online (Sandbox Code Playgroud)

这出错了:

error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
  --> src/lib.rs:14:5
   |
3 …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

16
推荐指数
1
解决办法
1836
查看次数

逻辑上拆分借用以解决启用 NLL 的借用检查器的限制是否安全?

下面的代码涉及一个非常微妙的借用检查器闪避。代码本身描述了推理。问题:

  • 这真的安全吗?
  • 这是表示执行的不安全操作的推荐方式吗?我应该使用指针吗?
  • 新的 Polonius 借用检查器能否推理出这样的模式?
/// Insert a new data element at a given key.
pub fn insert<'a, K: Eq, V>(this: &'a mut Vec<(K, V)>, key: K, val: V) -> &'a mut V {
    // Safety: As indicated below, we would like to return val1 directly in the loop,
    // but rust will reject this, claiming a double borrow, and we instead use some
    // unsafe hacks to circumvent the borrow checker. To show this is safe, consider
    // …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

5
推荐指数
1
解决办法
273
查看次数

删除不可变借款以进行可变借款

我还在学习Rust,在尝试将Dikjstra作为培训项目的一部分时,我遇到了这种特殊的问题.首先我定义一个HashMap:

let mut dist: HashMap<Node, usize> = HashMap::new();
Run Code Online (Sandbox Code Playgroud)

然后:

let state = State { node: next_node.clone(), cost: cost + 1 };
let current_dist = dist.get(&state.node);
if (current_dist == None) || (state.cost < *current_dist.unwrap()) {
    dist.insert(state.node.clone(), state.cost);
    heap.push(state);
}
Run Code Online (Sandbox Code Playgroud)

这产生了一个编译错误,因为dist.get触发了一个不可变的借位,它在if ... {...}语句之后一直保留在范围内,特别是当我dist.insert要求一个可变的借位时.

我想我错过了一个模式或关键字,允许我这种类型的过程.现在我尝试了范围drop的开头if,以及其他current_dist评估

let current_dist;
{
    current_dist = dist.get(&state.node);
}
Run Code Online (Sandbox Code Playgroud)

要么

let current_dist = {|| dist.get(&state.node)}();
Run Code Online (Sandbox Code Playgroud)

但是,在if声明之后,仍然会发生不可变借款的范围.

rust borrow-checker

3
推荐指数
1
解决办法
536
查看次数

获取对 Vec 元素的可变引用或创建新元素并获取该引用

我有一个Vec<State>列表,想要搜索一个元素并获取对其的可变引用。如果不存在,则应创建一个新的默认元素并将其添加到列表中:

struct State {
    a: usize,
}

fn print_states(states: &Vec<State>) {
    for state in states {
        print!("State{{a:{}}} ", state.a);
    }
    println!();
}

fn main() {
    let mut states = vec![State { a: 1 }, State { a: 2 }, State { a: 3 }];

    print_states(&states);

    let mut state = match states.iter_mut().find(|state| state.a == 2) {
        Some(state) => state,
        None => {
            let new_state = State { a: 3 };
            states.push(new_state);
            states.last().unwrap()
        }
    };
    state.a = 4;
    drop(state);
    print_states(&states); …
Run Code Online (Sandbox Code Playgroud)

reference mutable rust

3
推荐指数
1
解决办法
2154
查看次数