相关疑难解决方法(0)

如何有效地从HashMap中查找和插入?

我想做以下事情:

  • 查找Vec某个键,并将其存储起来供以后使用.
  • 如果它不存在,Vec则为该键创建一个空,但仍将其保留在变量中.

如何有效地做到这一点?当然我以为我可以使用match:

use std::collections::HashMap;

// This code doesn't compile.
let mut map = HashMap::new();
let key = "foo";
let values: &Vec<isize> = match map.get(key) {
    Some(v) => v,
    None => {
        let default: Vec<isize> = Vec::new();
        map.insert(key, default);
        &default
    }
};
Run Code Online (Sandbox Code Playgroud)

当我尝试它时,它给了我错误,如:

error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
  --> src/main.rs:11:13
   |
7  |     let values: &Vec<isize> = match map.get(key) {
   |                                     --- immutable borrow occurs …
Run Code Online (Sandbox Code Playgroud)

lookup hashmap rust

83
推荐指数
1
解决办法
1万
查看次数

什么是非词汇生命?

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

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

lifetime rust lifetime-scoping

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

为什么匹配的可变引用的条件赋值会导致借用错误?

我无法理解为什么这会导致错误:

#[derive(Debug)]
pub struct Node {
    next: Option<Box<Node>>,
}

pub fn print_root_or_next(root: &mut Node, try_next: bool) {
    let mut current = root;
    match &mut current.next {
        Some(node) => {
            if try_next {
                current = &mut *node;
            }
        }
        None => return,
    }

    println!("{:?}", current);
}
Run Code Online (Sandbox Code Playgroud)
#[derive(Debug)]
pub struct Node {
    next: Option<Box<Node>>,
}

pub fn print_root_or_next(root: &mut Node, try_next: bool) {
    let mut current = root;
    match &mut current.next {
        Some(node) => {
            if try_next {
                current = …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

11
推荐指数
1
解决办法
286
查看次数

为什么这个可变借用超出了它的范围?

在我期望可变借用结束之后,我遇到了关于同时使用可变和不可变借用的令人困惑的错误。我对类似问题(1 , 2 , 3 , 4 , 5)进行了大量研究,这让我相信我的问题与词法生命周期有关(尽管打开 NLL 功能并每晚编译并没有) t 改变结果),我只是不知道是什么;我的情况似乎不适合其他问题的任何场景。

pub enum Chain<'a> {
    Root {
        value: String,
    },
    Child {
        parent: &'a mut Chain<'a>,
    },
}

impl Chain<'_> {
    pub fn get(&self) -> &String {
        match self {
            Chain::Root { ref value } => value,
            Chain::Child { ref parent } => parent.get(),
        }
    }

    pub fn get_mut(&mut self) -> &mut String {
        match self {
            Chain::Root { ref mut value } => …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

11
推荐指数
1
解决办法
476
查看次数

即使使用NLL,循环中也会发生双重可变借用错误

假设我有几个结构,如下例所示,在next()方法中我需要使用用户提供的缓冲区来拉下一个事件,但是如果这个事件是注释,并且忽略comments标志设置为true,我需要拉下一个事件:

struct Parser {
    ignore_comments: bool,
}

enum XmlEvent<'buf> {
    Comment(&'buf str),
    Other(&'buf str),
}

impl Parser {
    fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
        let result = loop {
            buffer.clear();

            let temp_event = self.parse_outside_tag(buffer);

            match temp_event {
                XmlEvent::Comment(_) if self.ignore_comments => {}
                _ => break temp_event,
            }
        };
        result
    }

    fn parse_outside_tag<'buf>(&mut self, _buffer: &'buf mut String) -> XmlEvent<'buf> {
        unimplemented!()
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,即使#![feature(nll)]启用了以下代码,此代码也会出现双重借用错误:

error[E0499]: cannot borrow `*buffer` as mutable more than …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

9
推荐指数
2
解决办法
489
查看次数

根据最后一个元素将某些东西推入向量

我想得到一个向量的最后一个元素并用它来确定下一个要推入的元素.这是一个例子,它不起作用,但它显示了我想要实现的目标:

let mut vector: Vec<i32> = Vec::new();

if let Some(last_value) = vector.last() {
    vector.push(*last_value + 1);
}
Run Code Online (Sandbox Code Playgroud)

push当矢量也被不可靠地借用时我无法使用:

error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable
 --> src/main.rs:5:9
  |
4 |     if let Some(last_value) = vector.last() {
  |                               ------ immutable borrow occurs here
5 |         vector.push(*last_value + 1);
  |         ^^^^^^ mutable borrow occurs here
6 |     }
  |     - immutable borrow ends here
Run Code Online (Sandbox Code Playgroud)

这样做有什么好办法?

rust borrow-checker

6
推荐指数
1
解决办法
985
查看次数

如何查找或插入 Vec

我正在尝试编写一个函数,该函数查找返回对 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)

游乐场链接:https://play.rust-lang.org/?version= stable&mode=debug&edition=2018&gist=cb12c38bcf3682b15a247d14aab48b6b

Rust 给出了以下编译器错误(通过游乐场链接的完整消息):

error[E0499]: cannot borrow `*vec` as mutable more than once at a time
Run Code Online (Sandbox Code Playgroud)

这似乎应该可以在 Rust 中实现,但是我不清楚如何重新实现它以避免借用检查器错误。

rust borrow-checker

6
推荐指数
1
解决办法
6910
查看次数

在HashMap-value之后匹配比克隆它更优雅的方式

我正在使用Rust编程语言学习Rust .我在处理闭包章节中正在处理以下任务:

尝试修改Cacher以保存哈希映射而不是单个值.哈希映射的键将arg是传入的值,并且哈希映射的值将是在该键上调用闭包的结果.值函数不会查看是否self.value直接具有值SomeNone值,而是arg在哈希映射中查找并返回值(如果存在).如果它不存在,Cacher则将调用闭包并将结果值保存在与其arg值相关联的哈希映射中.

这是我的解决方案:

use std::collections::HashMap;

struct Cacher<T>
where
    T: Fn(i32) -> i32,
{
    calculation: T,
    values: HashMap<i32, i32>,
}

impl<T> Cacher<T>
where
    T: Fn(i32) -> i32,
{
    fn new(calculation: T) -> Cacher<T> {
        Cacher {
            calculation,
            values: HashMap::new(),
        }
    }
    fn value(&mut self, arg: i32) -> i32 {
        match self.values.get(&arg) {
            Some(v) => *v,
            None => { …
Run Code Online (Sandbox Code Playgroud)

hash caching rust

5
推荐指数
0
解决办法
408
查看次数

如何在Vec上更新或插入?

我在Rust写一个数据结构.它包含一Vec对键值对.当插入到结构中时,我需要找到匹配的键并更新键和值(实际上是子指针).代码看起来有点像这样,其中pivots是一个ref mutto Vec<Pivot>,Pivot它只是一个包含两个字段的结构:

match pivots.iter_mut().find(|ref p| key <= p.min_key) { // first mutable borrow
    Some(ref mut pivot) => {
        // If there is one, insert into it and update the pivot key
        pivot.min_key = key;
        pivot.child.insert(key, value) // recursive call
    },
    // o/w, insert a new leaf at the end
    None => pivots.push(Pivot /* ... */) // second mutable borrow
}
Run Code Online (Sandbox Code Playgroud)

但是有一个问题.即使我没有在第二部分中使用可变迭代器match,借用检查器也会抱怨我"不能*pivots一次多次借用可变的迭代".

这对我来说是完全合理的,因为第一次借用仍然在范围内,即使它没有在那种情况下使用match.这有点不方便:一个聪明的检查员当然可以说借用是不重叠的.我见过有人在线建议使用早期返回以避免问题,如下所示:

match pivots.iter_mut().find(|ref …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

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

使用可变引用遍历递归结构并返回最后一个有效引用

我试图递归一个节点结构,修改它们,然后返回Node我得到的最后一个。我使用非词法生命周期 RFC 中示例解决了循环中可变引用的问题。如果我尝试将可变引用返回到 last Node,则会出现use of moved value错误:

#[derive(Debug)]
struct Node {
    children: Vec<Node>,
}

impl Node {
    fn new(children: Vec<Self>) -> Self {
        Self { children }
    }
    fn get_last(&mut self) -> Option<&mut Node> {
        self.children.last_mut()
    }
}

fn main() {
    let mut root = Node::new(vec![Node::new(vec![])]);

    let current = &mut root;

    println!("Final: {:?}", get_last(current));
}


fn get_last(mut current: &mut Node) -> &mut Node {
    loop {
        let temp = current; …
Run Code Online (Sandbox Code Playgroud)

reference mutable rust borrowing

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