为什么在可变引用上调用方法会涉及“借用”?

2024-03-16

我正在学习 Rust,我正在尝试将这段代码进行编译:

use std::vec::Vec;
use std::collections::BTreeMap;

struct Occ {
    docnum: u64,
    weight: f32,
}

struct PostWriter<'a> {
    bytes: Vec<u8>,
    occurrences: BTreeMap<&'a [u8], Vec<Occ>>,
}

impl<'a> PostWriter<'a> {
    fn new() -> PostWriter<'a> {
        PostWriter {
            bytes: Vec::new(),
            occurrences: BTreeMap::new(),
        }
    }

    fn add_occurrence(&'a mut self, term: &[u8], occ: Occ) {
        let occurrences = &mut self.occurrences;
        match occurrences.get_mut(term) {
            Some(x) => x.push(occ),
            None => {
                // Add the term bytes to the big vector of all terms
                let termstart = self.bytes.len();
                self.bytes.extend(term);
                // Create a new occurrences vector
                let occs = vec![occ];
                // Take the appended term as a slice to use as a key
                // ERROR: cannot borrow `*occurrences` as mutable more than once at a time
                occurrences.insert(&self.bytes[termstart..], occs);
            }
        }
    }
}

fn main() {}

我收到错误:

error[E0499]: cannot borrow `*occurrences` as mutable more than once at a time
  --> src/main.rs:34:17
   |
24 |         match occurrences.get_mut(term) {
   |               ----------- first mutable borrow occurs here
...
34 |                 occurrences.insert(&self.bytes[termstart..], occs);
   |                 ^^^^^^^^^^^ second mutable borrow occurs here
35 |             }
36 |         }
   |         - first borrow ends here

我不明白......我只是在可变引用上调用一个方法,为什么该行会涉及借用?


我只是在可变引用上调用一个方法,为什么该行会涉及借用?

当您调用一个对象上的方法来改变该对象时,您不能任何其他参考资料到那个突出的对象。如果这样做,您的突变可能会使这些引用无效并使您的程序处于不一致的状态。例如,假设您从哈希图中获取了一个值,然后添加了一个新值。添加新值会达到魔法极限并强制重新分配内存,您的值现在指向任何地方!当您使用该值时...程序就会运行!

在这种情况下,您似乎想要执行相对常见的“如果丢失则追加或插入”操作。你会想要使用entry http://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.entry为了那个原因:

use std::collections::BTreeMap;

fn main() {
    let mut map = BTreeMap::new();

    {
        let nicknames = map.entry("joe").or_insert(Vec::new());
        nicknames.push("shmoe");

        // Using scoping to indicate that we are done with borrowing `nicknames`
        // If we didn't, then we couldn't borrow map as
        // immutable because we could still change it via `nicknames`
    }

    println!("{:?}", map)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在可变引用上调用方法会涉及“借用”? 的相关文章

  • 如何限制Cargo.toml中的测试线程数?

    我的测试共享公共资源并且无法同时执行 这些测试失败cargo test 但与RUST TEST THREADS 1 cargo test 我可以修改测试以等待全局互斥体 但如果有任何更简单的方法来强制 我不想让它们混乱cargo为我设置这个
  • 对向量的引用仍然打印为向量?

    愚蠢的 n00b 试图了解一点 Rust 这是我的程序 fn main let v vec 1 2 3 println v println v 产生输出 1 2 3 1 2 3 重点是什么 我一半期待它打印一个内存地址 我最初是被这个抛出的
  • serde_json::from_str 错误,其中字符串来自文件

    extern crate serde json use serde json Value use std fs File use std io prelude fn main let filepath map test anhui txt
  • 包含原始指针的结构可以实现 Send 并且 FFI 安全吗?

    我有一个场景 Rust 会调用 Cmalloc缓冲区并将结果指针存储到结构中 稍后 该结构将被移动到线程并传递给 C 函数 该函数会对其进行变异 我的问题的天真的方法看起来像这样 extern crate libc use libc c v
  • 解析 Rust FFI 中的联合结构

    我在解析 c union 结构 XEvent 时遇到问题 我正在 Rust 中试验 Xlib 和 X Record Extension 我生成 ffi 绑定Rust 绑定根 https github com crabtw rust bind
  • 为什么在闭包参数中使用“&&”?

    我有两个问题这个例子 https doc rust lang org std iter trait Iterator html method find let a 1 2 3 assert eq a iter find x x 2 Some
  • 在 Rust 中,如何检查泛型参数是否属于特定类型并强制转换为它

    我有几种实现特征 关系 的类型 我需要在它们之间传递数据 例如INSERT INTO FROM SELECT来自 sql 但是 有时我会移动来自同一类型的数据 这意味着我可以使用更直接的方式 impl Relation for BTree
  • 在编译时检查指针大小

    我发现类似的问题编译时泛型类型大小检查 https stackoverflow com questions 30330519 compile time generic type size check 但没有收到任何答复 问题是通过FFI u
  • 从 WebAssembly .wasm 模块获取 JavaScript 导入对象条目

    我想了解 Rust 程序在编译为 wasm 文件时实际导出的内容 以便我可以提供有效的importObject到实例化函数 WebAssembly instantiate bufferSource importObject 据我了解 执行此
  • 为什么我要使用发散函数?

    读 Rust 书时 我发现一个有趣的话题 发散函数 https doc rust lang org stable book first edition functions html diverging functions Rust 有一些特
  • 检查自定义结构的相等性

    我正在尝试检查两个 功能相同 结构的相等性 derive PartialEq Debug pub struct TypeA lt a gt a str derive PartialEq Debug pub struct TypeB lt a
  • 无法返回对临时值的引用

    我正在尝试学习 Rust 同时我想尝试将结构对象转换为字节数组 但这样做遇到了问题 所以我有这个 struct Node lt a gt id u8 name a str data a str impl lt a gt Node lt a
  • Rust 元组参考和参考元组

    元组引用和作为类型引用的元组之间有什么关系 为什么第一个有效但第二个不行 let a 1 let b 2 This works c i32 d i32 let c d a b type TupleOfRef lt a gt a i32 a
  • Rust 迭代器和 C++ 迭代器之间的主要区别是什么? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 C 迭代器的一个典型示例是指针 可用于指向 C 数组中的元素 如下所示 int array 1 2 3 4 int begin std
  • 返回数组大小的关联常量[重复]

    这个问题在这里已经有答案了 考虑以下trait pub trait Representable const SIZE usize fn get self gt u8 SIZE fn set mut self value u8 SIZE 我想
  • 有没有一种方法可以“展平”Rust 中的(反)序列化枚举?

    我有一个由其他枚举组成的枚举 类似于以下内容 serde为简洁起见 省略了派生和注释 enum Main A SubA B SubB enum SubA X1 X2 X3 enum SubB Y1 Y2 Y3 我很想能够使用serde反序列
  • 我可以有效地从 HashSet 中随机采样吗?

    我有一个std collections HashSet 我想采样并删除一个均匀随机的元素 目前 我正在做的是使用随机抽样索引rand gen range 然后迭代HashSet到该索引来获取元素 然后我删除选定的元素 这可行 但效率不高 有
  • 用于解析 Rust 中的匹配臂的递归宏

    我正在尝试编写一个宏来将一组规则扩展为执行标记匹配的代码 但无法在不导致宏扩展错误的情况下生成正确的代码 我知道我可以通过其他方式处理这个问题 但这里的关键问题不是如何解析令牌 而是如何编写一个可以使用匹配臂递归扩展令牌树的宏 这个想法是我
  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • Rust 中声明变量的宏?

    在 C 中 可以编写声明变量的宏 如下所示 define VARS a b c int a b c 当然 这不是您通常想要做的事情 在实际的例子中 我希望开始工作 但它并不那么简单 define VARS data stride a b c

随机推荐