【发布时间】: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