我有一个自定义特性,用作切片中的元素类型:
pub trait IConstraint {
// members here
}
pub struct Scenario<'a> {
pub constraints: &'a [Box<dyn IConstraint>]
}
我想提供一个add_constraint
方法,它可以对切片进行写时复制.类似这样:
impl<'a> Scenario<'a> {
pub fn add_constraint(&mut self, constraint: Box<dyn IConstraint<TNodeState>>) {
let mut constraints: Vec<Box<dyn IConstraint<TNodeState>>> = Vec::new();
constraints.copy_from_slice(self.constraints);
constraints.push(constraint);
self.constraints = &constraints;
}
}
问题是我遇到了以下错误:
trait 界限
Box<dyn IConstraint<TNodeState>>: std::marker::Copy
不满足
好的,所以Box<T>
没有实现Copy
的特性.很公平.但我该如何解决这个问题呢?理想情况下,我会重用这些框或至少是约束,因为它们是不可变的.但是,如果由于所有权规则不可靠,我无法做到这一点,那么我如何在盒子类型上实现Copy
特性呢?我try 了各种方法,它们都会产生错误.
此try 会产生"在具有析构函数的类型上不允许复制":
impl<TNodeState> Copy for Box<dyn IConstraint<TNodeState>> {
}
克隆呢?我可以切换到constraints.clone_from_slice(self.constraints);
,但在IConstraint
上实现Clone
trait会产生一系列"IConstraint不能生成对象"错误.
即使我可以让box可克隆,当然我也会从我的add_constraint
方法中得到预期的borrow 生命周期 缺陷:
借来的价值活得不够长
那么,我是否必须抛弃我的add_constraint
个函数的 idea ,并强制我的 struct 的所有者手动复制它?鉴于我的实际 struct 包含3个字段,这变得很乏味,因为所有者现在必须将字段解构为局部变量,以便删除不可变的borrow ,从而允许原始向量发生变异:
fn add_remove_constraint() {
let mut scenario = Scenario::<&str, bool, 3_usize>::new(&["A", "B", "C"]);
let mut constraints: Vec<Box<dyn IConstraint<bool>>> = Vec::new();
constraints.push(Box::new(SelectionCountConstraint {
nodes: [1, 2],
min: 1,
max: 2,
}));
scenario = Scenario {
constraints: &constraints,
..scenario
};
assert_eq!(1, scenario.get_constraints().len());
let nodes = scenario.nodes;
let selection_state = scenario.selection_state;
constraints.pop();
scenario = Scenario {
constraints: &constraints,
nodes,
selection_state,
};
assert_eq!(0, scenario.get_constraints().len());
}