【问题标题】:How can I create a caching object factory in Rust?如何在 Rust 中创建缓存对象工厂?
【发布时间】:2021-04-04 15:21:38
【问题描述】:

我想用 Rust 开发一个布尔公式库,我对 Rust 还很陌生。

我们的想法是拥有由(显然是可变的)公式工厂创建和缓存的不可变公式。因此,用户将首先创建一个公式工厂,然后使用它来创建作为引用返回的公式。

问题是编译器基本上不允许我创建多个公式,因为这意味着公式工厂对象的可变借用不止一个。

let mut f = FormulaFactory::new();
let a = f.variable("a");
let b = f.variable("b"); // error: cannot borrow `f` as mutable more than once at a time
let ab = f.and(a, b);

我理解这种违反规则的行为,但另一方面,我认为在这种情况下一切都会好起来的(至少在单线程设置中)。有没有一种简单的方法来解决这个问题,还是我必须考虑一种不同的、更兼容 rust 的方法?

更多信息:'static 生命周期在目标场景中不是一个选项。用户可能希望创建多个公式工厂,尤其是在不再需要公式时删除它们。

仅作为一个最小示例的参考(非常简化 - 显然 Formula 也将具有公式类型,在此示例中只有变量和连词):

#![feature(hash_set_entry)]
use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash)]
pub struct Formula<'a> {
    variable: Option<&'a str>,
    operands: Vec<&'a Formula<'a>>,
}

pub struct FormulaFactory<'a> {
    variables: HashSet<Formula<'a>>,
    conjunctions: HashSet<Formula<'a>>,
}

impl<'a> FormulaFactory<'a> {
    pub fn new() -> FormulaFactory<'a> {
        FormulaFactory {
            variables: HashSet::new(),
            conjunctions: HashSet::new(),
        }
    }

    pub fn variable(&mut self, name: &'a str) -> &Formula<'a> {
        (&mut self.variables).get_or_insert(Formula{variable: Some(name), operands: vec![]})
    }
    
    pub fn and(&mut self, op1: &'a Formula<'a>, op2: &'a Formula<'a>) -> &Formula<'a> {
        (&mut self.conjunctions).get_or_insert(Formula{variable: None, operands: vec![op1, op2]})
    }
}

fn main() {
    let mut f = FormulaFactory::new();
    let a = f.variable("a");
    let b = f.variable("b"); // error: cannot borrow `f` as mutable more than once at a time
    let ab = f.and(a, b);
    
    println!("{}", ab.operands[0].variable.unwrap())
}

【问题讨论】:

    标签: rust borrow-checker


    【解决方案1】:

    变量af 对象中包含的引用。只要您有a 的引用,您就不能修改f,因为它已经被a 别名。我认为解决这个问题的最好方法是在 FormulaFactory 结构中添加一个 FormulaVec,称为 formulas(为了简单起见),并且只给出 FormulaIndex 对象,这只是一个 @ 987654332@ 表示Formulaformulas 字段中的索引。这与petgraph 采用的方法相同,其中Graph 中的nodes 字段包含NodeVec,但Graph api 仅给出NodeIndex 对象。

    【讨论】:

      猜你喜欢
      • 2010-11-21
      • 1970-01-01
      • 2012-02-05
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多