相关疑难解决方法(0)

为什么我不能在同一个结构中存储值和对该值的引用?

我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:

struct Thing {
    count: u32,
}

struct Combined<'a>(Thing, &'a u32);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing { count: 42 };

    Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)

有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:

struct Combined<'a>(Thing, &'a Thing);

fn make_combined<'a>() -> Combined<'a> {
    let thing = Thing::new();

    Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)

有时,我甚至没有参考该值,我得到同样的错误:

struct Combined<'a>(Parent, Child<'a>);

fn make_combined<'a>() -> Combined<'a> {
    let parent = Parent::new();
    let child = parent.child();

    Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)

在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?

lifetime rust borrow-checker

193
推荐指数
3
解决办法
2万
查看次数

如何有效地从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万
查看次数

不能借用为不可变的因为它在函数参数中也被借用为可变的

这里发生了什么(游乐场)?

struct Number {
    num: i32
}

impl Number {
    fn set(&mut self, new_num: i32) {
        self.num = new_num;
    }
    fn get(&self) -> i32 {
        self.num
    }
}

fn main() {
    let mut n = Number{ num: 0 };
    n.set(n.get() + 1);
}
Run Code Online (Sandbox Code Playgroud)

给出了这个错误:

error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
  --> <anon>:17:11
   |
17 |     n.set(n.get() + 1);
   |     -     ^          - mutable borrow ends here
   |     |     |
   |     | …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

21
推荐指数
1
解决办法
3400
查看次数

想要使用模式匹配添加到HashMap,一次多次获取可变的可变性

我正在尝试编写一些玩具代码,用于存储它在一个单词中看到单词的次数HashMap.如果密钥存在,则将计数器递增1,如果密钥不存在,则将其与值相加1.我本能地希望用模式匹配来做这个,但是我不止一次地尝试了一个可变的错误:

fn read_file(name: &str) -> io::Result<HashMap<String, i32>> {
    let b = BufReader::new(File::open(name)?);
    let mut c = HashMap::new();

    for line in b.lines() {
        let line = line?;
        for word in line.split(" ") {
            match c.get_mut(word) {
                Some(i) => {
                    *i += 1;
                },
                None => {
                    c.insert(word.to_string(), 1);
                }
            }
        }
    }

    Ok(c)
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

error[E0499]: cannot borrow `c` as mutable more than once at a time
  --> <anon>:21:21
   |
16 |             match c.get_mut(word) {
   |                   - …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

16
推荐指数
2
解决办法
2109
查看次数

在迭代递归结构时无法获得可变引用:不能一次多次借用可变引用

我试图迭代地导航递归数据结构,以便在某个位置插入元素.根据我的有限理解,这意味着对结构的根进行可变引用,并通过对其跟随者的引用连续替换它:

type Link = Option<Box<Node>>;

struct Node {
    next: Link
}

struct Recursive {
    root: Link
}

impl Recursive {
    fn back(&mut self) -> &mut Link {
        let mut anchor = &mut self.root;
        while let Some(ref mut node) = *anchor {
            anchor = &mut node.next;
        }
        anchor
    }
}
Run Code Online (Sandbox Code Playgroud)

(Rust操场链接)

但是,这失败了:

error[E0499]: cannot borrow `anchor.0` as mutable more than once at a time
  --> src/main.rs:14:24
   |
14 |         while let Some(ref mut node) = *anchor {
   |                        ^^^^^^^^^^^^
   |                        | …
Run Code Online (Sandbox Code Playgroud)

mutable rust borrowing

16
推荐指数
3
解决办法
2405
查看次数

从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
查看次数

当返回消耗StdinLock的结果时,为什么借用stdin保留?

鉴于以下功能:

use std::io::{BufRead, stdin};

fn foo() -> usize {
    let stdin = stdin();
    let stdinlock = stdin.lock();
    stdinlock
        .lines()
        .count()
}
Run Code Online (Sandbox Code Playgroud)

无法编译时出现以下错误:

error: `stdin` does not live long enough
  --> src/main.rs:12:1
   |
7  |     let stdinlock = stdin.lock();
   |                     ----- borrow occurs here
...
11 | }
   | ^ `stdin` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created
Run Code Online (Sandbox Code Playgroud)

我觉得这很令人惊讶,因为使用锁(via lines)的结果不会保留对原始源的任何引用.事实上,在返回之前为绑定指定相同的结果工作正常(Playground).

fn bar() -> usize …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

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

为什么借入仍然存在于if的else块中?

为什么self.f2()以下代码中的调用会使借用检查程序运行?是不是在另一个范围内的else块?这是一个相当难的问题!

use std::str::Chars;

struct A;

impl A {
    fn f2(&mut self) {}

    fn f1(&mut self) -> Option<Chars> {
        None
    }

    fn f3(&mut self) {
        if let Some(x) = self.f1() {

        } else {
            self.f2()
        }
    }
}

fn main() {
    let mut a = A;
}
Run Code Online (Sandbox Code Playgroud)

操场

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/main.rs:16:13
   |
13 |         if let Some(x) = self.f1() {
   |                          ---- first mutable borrow occurs here
... …
Run Code Online (Sandbox Code Playgroud)

rust

10
推荐指数
2
解决办法
2384
查看次数

如何使用HashMap作为累加器进行折叠?

此代码有效:

let stdin = std::io::stdin();
let mut rdr = csv::Reader::from_reader(stdin);
let mut hmap = HashMap::<String, u64>::new();

rdr.records()
    .map(|r| r.unwrap())
    .fold((), |_, item| {
        // TODO: Is there a way not to have to copy item[col] every time?
        let counter = hmap.entry(item[col].to_string()).or_insert(0);
        *counter += 1;
    });
Run Code Online (Sandbox Code Playgroud)

此代码失败并显示消息:"无法移出,acc因为它是借用的"

let stdin = std::io::stdin();
let mut rdr = csv::Reader::from_reader(stdin);
let hmap = rdr.records()
    .map(|r| r.unwrap())
    .fold(HashMap::<String, u64>::new(), |mut acc, item| {
        // TODO: Is there a way not to have to copy …
Run Code Online (Sandbox Code Playgroud)

rust

10
推荐指数
1
解决办法
1972
查看次数

如何从数组中移出值?

我拥有一个3号数组的所有权,我想迭代它,随着我的去向移动元素.基本上,我想IntoIterator实现一个固定大小的数组.

由于数组没有在标准库中实现这个特性(我理解为什么),是否有解决方法来获得所需的效果?我的对象不是Copy也不是Clone.我可以Vec从数组中创建一个然后迭代进入Vec,但我甚至不确定如何做到这一点.

(有关信息,我想完成一系列的Complete)

这是一个简单的情况示例(天真的iter()尝试):

// No-copy, No-clone struct
#[derive(Debug)]
struct Foo;

// A method that needs an owned Foo
fn bar(foo: Foo) {
    println!("{:?}", foo);
}

fn main() {
    let v: [Foo; 3] = [Foo, Foo, Foo];

    for a in v.iter() {
        bar(*a);
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:14:13
   |
14 |         bar(*a);
   |             ^^ cannot move out of …
Run Code Online (Sandbox Code Playgroud)

arrays move rust

10
推荐指数
3
解决办法
1962
查看次数

标签 统计

rust ×10

borrow-checker ×4

lifetime ×2

arrays ×1

borrowing ×1

hashmap ×1

lookup ×1

move ×1

mutable ×1