小编use*_*156的帖子

保存可变引用,以备日后使用别名

我正在尝试实现像拉链这样的东西,但是利用可变引用来避免在我移动时不得不解构和重构数据结构.我有一个链接列表尝试的示例代码,尽管我最好将其应用于其他结构,如树.

pub enum List<T> {
    Empty,
    Cons { head: T, tail: Box<List<T>> },
}

pub struct Zipper<'a, T: 'a> {
    trail: Option<Box<Zipper<'a, T>>>,
    focus: &'a mut List<T>,
}

impl<'a, T: 'a> Zipper<'a, T> {
    pub fn down(&'a mut self) {
        match self.focus {
            &mut List::Empty => (),
            &mut List::Cons {
                tail: ref mut xs, ..
            } => {
                //We need a way to convince rust that we won't use oldZipper
                //until xs goes out of scope
                let oldZipper = std::mem::replace( …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

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

Rust 中的安全缓存无需重新计数

我正在尝试编写一个返回某种列表的函数。由于这个函数是纯函数,并且我可能会多次调用它,因此我想缓存结果。为了避免分配,我想返回所有都指向同一内存位置的引用,这样我只需要在每次函数的唯一调用时执行一次分配。

原则上,我可以将每个结果作为向量存储在缓存中,并返回对结果向量切片的引用。这看起来不安全,但(我认为)事实并非如此。如果您从不删除或修改缓存的元素,那么您的切片引用就是安全的。当您添加到缓存时,矢量可能会移动,但它们的切片不应移动。

显然借用检查器不会接受这个解决方案。就其而言,当函数返回时,缓存被借用,并且您不能再次调用它,因为这需要可变借用。

到目前为止,我拥有的最佳解决方案是在此处的操场上,包括如下:

use std::collections::HashMap;
use std::rc::Rc;

fn n_trues(n: usize, cache: &mut HashMap<usize, Rc<[bool]>>) -> Rc<[bool]> {
    cache
        .entry(n)
        .or_insert_with(|| vec![true; n].into())
        .clone()
}

fn main() {
    let mut cache = HashMap::new();
    let zero = n_trues(0, &mut cache);
    let one = n_trues(1, &mut cache);
    let other_zero = n_trues(0, &mut cache);
    assert!(Rc::ptr_eq(&zero, &other_zero));
    for x in [zero, one, other_zero].iter() {
        println!("{:?}", x);
    }
}
Run Code Online (Sandbox Code Playgroud)

满足Rc借用检查器:从缓存中删除不会使其他引用无效,并且您不能改变Rc. 然而,实际的引用计数是多余的:我们确保缓存仅在程序结束时超出范围,因此在此之前缓存的值不会被释放。这是借用检查器可以检查的事情:它可以确保缓存的寿命比所有结果都长。

有没有什么方法可以消除引用计数而不诉诸不安全代码?

caching rust

4
推荐指数
1
解决办法
952
查看次数

标签 统计

rust ×2

borrow-checker ×1

caching ×1