标签: borrowing

我应该如何重构我的图形代码以避免“一次不能多次借用可变变量”错误?

我有一个成功编译的简单图表:

use std::collections::HashMap;

type Key = usize;
type Weight = usize;

#[derive(Debug)]
pub struct Node<T> {
    key: Key,
    value: T,
}
impl<T> Node<T> {
    fn new(key: Key, value: T) -> Self {
        Node {
            key: key,
            value: value,
        }
    }
}

#[derive(Debug)]
pub struct Graph<T> {
    map: HashMap<Key, HashMap<Key, Weight>>,
    list: HashMap<Key, Node<T>>,
    next_key: Key,
}
impl<T> Graph<T> {
    pub fn new() -> Self {
        Graph {
            map: HashMap::new(),
            list: HashMap::new(),
            next_key: 0,
        }
    }
    pub fn add_node(&mut self, value: …
Run Code Online (Sandbox Code Playgroud)

lifetime rust borrowing

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

在盒装未来中使用引用变量时“需要显式生命周期”

我正在尝试使用创建的结构main()并将其传递给返回盒装Future. 然而,我遇到了终身和借贷问题,似乎无法彻底解决这个问题。

这是我的结构和函数:

extern crate futures; // 0.1.21
extern crate tokio_core; // 0.1.17

use futures::{future::ok, Future};

pub struct SomeStruct {
    some_val: u32,
}

impl SomeStruct {
    pub fn do_something(&self, value: u32) -> u32 {
        // Do some work
        return self.some_val + value;
    }
}

fn main() {
    let core = tokio_core::reactor::Core::new().unwrap();
    let my_struct = SomeStruct { some_val: 10 };

    let future = get_future(&my_struct);
    core.run(future);

    let future2 = get_future(&my_struct);
    core.run(future2);
}

fn get_future(some_struct: &SomeStruct) -> Box<Future<Item = …
Run Code Online (Sandbox Code Playgroud)

future lifetime rust borrowing rust-tokio

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

如何借用字段进行序列化但在反序列化期间创建它?

我有一个这样的结构:

#[derive(Serialize, Deserialize)]
struct Thing {
    pub small_header: Header,
    pub big_body: Body,
}
Run Code Online (Sandbox Code Playgroud)

我想将其序列化Thing以通过网络发送。我已经有一个Body可用的但我无法移动它(想象一下我正在用它做某事,我不时收到一个命令来暂时停止我正在做的事情并发送我现在拥有的任何数据)并且我可以不要复制它(它太大了,可能有数百兆字节)。

所以我希望 Serde 只借用我所拥有的序列化它,因为它不需要为此移动到结构中。如果我重写Thing拿个参考,我显然推不出来Deserialize

我一直在使用的解决方法是Arc<Body>在我的代码中使用一个,这样我就可以在我的正常逻辑中使用主体,当我需要序列化它时,我可以做一个廉价的克隆并将其Arc<Body>放入结构中进行序列化. 在反序列化期间,Serde 将创建Arc一个引用计数为 1的新对象。

这仍然涉及散布Arc在我的代码中,这不是很好,更不用说不必要的(尽管很小)运行时成本。此用例的正确解决方案是什么?

有趣的是,如果我不必发送标头,那么这将不是问题,因为我可以按引用序列化并按值反序列化,但是标头的存在使这变得不可能。我觉得我错过了一些关于 Serde 如何在这里借用数据的信息......

rust borrowing serde

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

使用进度条提取存档 - 可变借用错误

我正在尝试提取.tar.bz文件(或.tar.whatever),并且还能够获得xx%进度报告.到目前为止我有这个:

pub fn extract_file_with_progress<P: AsRef<Path>>(&self, path: P) -> Result<()> {
    let path = path.as_ref();
    let size = fs::metadata(path)?;
    let mut f = File::open(path)?;
    let decoder = BzDecoder::new(&f);
    let mut archive = Archive::new(decoder);

    for entry in archive.entries()? {
        entry?.unpack_in(".")?;
        let pos = f.seek(SeekFrom::Current(0))?;
    }

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

想法是用来pos/size获得百分比,但编译上面的函数会让我错误cannot borrow f as mutable because it is also borrowed as immutable.我理解错误的含义,但我并没有真正使用它f作为可变的; 我只使用搜索功能来获取当前位置.

有没有办法解决这个问题,要么强制编译器忽略可变借用,要么以某种不可变的方式获取位置?

file rust borrowing

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

如何检查两个引用变量是否借用了同一对象?

我有一个结构,所有存储只读引用,例如:

struct Pt { x : f32, y : f32, }
struct Tr<'a> { a : &'a Pt }
Run Code Online (Sandbox Code Playgroud)

我想impl Eq对于Tr测试,如果下伏a参考如出一辙Pt

let trBase1 = Pt::new(0.0, 0.0);
let trBase2 = Pt::new(0.0, 0.0);
assert!(trBase1 == trBase2);        // ok.
let tr1 = Tr::new(&trBase1);
let tr2 = Tr::new(&trBase2);
let tr3 = Tr::new(&trBase1);
assert!(tr1 == tr3);                // ok.
assert!(tr1.a == te2.a);            // ok. Using Eq for Pt that compare values.
assert!(tr1 != tr2);                // panicked! Not intended. …
Run Code Online (Sandbox Code Playgroud)

rust borrowing

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

支持 String 和 &amp;str 的 Hashmap

如何定义一个 HashMap 在其键和内容中都支持String&str?我尝试了以下方法:

fn mapping<T: Into<String>>() -> HashMap<T, T> {
  let mut map: HashMap<T, T> = HashMap::new();
  map.insert("first_name", "MyFirstName");
  map.insert("last_name".to_string(), "MyLastName".to_string());
  map
}

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

但它不编译,说:

error[E0599]: no method named `insert` found for type `std::collections::HashMap<T, T>` in the current scope
error[E0277]: the trait bound `T: std::cmp::Eq` is not satisfied
error[E0277]: the trait bound `T: std::hash::Hash` is not satisfied
Run Code Online (Sandbox Code Playgroud)

copy-on-write rust borrowing run-time-polymorphism

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

所有权、关闭、FnOnce:很多混乱

我有以下代码片段:

fn f<T: FnOnce() -> u32>(c: T) {
    println!("Hello {}", c());
}

fn main() {
    let mut x = 32;
    let g  = move || {
        x = 33;
        x
    };

    g(); // Error: cannot borrow as mutable. Doubt 1
    f(g); // Instead, this would work. Doubt 2
    println!("{}", x); // 32
}
Run Code Online (Sandbox Code Playgroud)

疑问1

我什至无法运行一次。

疑问2

...但我可以根据需要多次调用该闭包,只要我通过f. 有趣的是,如果我声明它FnMut,我会得到与疑问 1 相同的错误。

疑点3

和特征定义self中指的是什么?这就是关闭本身吗?还是环境?例如,来自文档:FnFnMutFnOnce

pub trait FnMut<Args>: FnOnce<Args> {
    extern "rust-call" …
Run Code Online (Sandbox Code Playgroud)

closures move mutable rust borrowing

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

我可以避免使用显式生命周期说明符而使用引用计数 (Rc) 吗?

我正在阅读 Rust Book,所有内容都很容易理解(感谢这本书的作者),直到关于生命周期的部分。我花了一整天,阅读了很多关于生命的文章,但我仍然对正确使用它们感到非常不安。

不过,我确实理解的是,显式生命周期说明符的概念旨在解决悬空引用的问题。我也知道 Rust 有引用计数智能指针 ( Rc),我相信它与shared_ptrC++ 中的相同,具有相同的目的:防止悬空引用。

鉴于这些生命周期对我来说是如此可怕,而且智能指针对我来说非常熟悉和舒适(我在 C++ 中经常使用它们),我可以避免使用智能指针的生命周期吗?还是生命周期是我必须在 Rust 代码中理解和使用的不可避免的事情?

reference reference-counting lifetime rust borrowing

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

为什么 Rust 可变借用发生在这里?

我正在学习 Rust,以下代码来自在线书籍The Rust Programming Language

fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s);

    s.clear(); // error!

    println!("the first word is: {}", word);
}


fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到这个:

C:/Users/administrator/.cargo/bin/cargo.exe run --color=always --package rust2 --bin rust2
   Compiling rust2 v0.1.0 (C:\my_projects\rust2)
error[E0502]: cannot borrow `s` as mutable because it is also …
Run Code Online (Sandbox Code Playgroud)

mutable rust borrowing

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

调用返回引用的函数时了解非词法生命周期

以下函数适用于 NLL

fn main() {
    let mut x = 1i32;
    let mut y = &mut x;

    let z = &mut y; 

    *y = 12;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我用let z = &mut y函数调用替换语句(基本上做同样的事情),借用检查器会抱怨。

fn test<'a>(x:&'a mut &'a mut i32) -> &'a mut i32 {
    &mut **x
}

fn main() {
    let mut x = 1i32;
    let mut y = &mut x;

    let z = test(&mut y);

    *y = 12;
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

error[E0506]: cannot assign to `*y` because it is borrowed
  --> …
Run Code Online (Sandbox Code Playgroud)

ownership rust borrow-checker borrowing

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