我有一个自定义特征,用作切片中的元素类型:
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;
}
}
问题是我收到此错误:
the trait bound
Box<dyn IConstraint<TNodeState>>: std::marker::Copy
is not satisfied the traitstd::marker::Copy
is not implemented forBox<dyn IConstraint<TNodeState>>
好的,那么 Box<T>
没有实现Copy
特征。很公平。但我该如何解决这个问题呢?理想情况下,我会重用这些框或至少重用约束,因为它们是不可变的。但如果由于 Rust 所有权规则我无法做到这一点,我该如何实现 Copy
盒子类型的特征?我尝试了各种方法,但都出现错误。
此尝试会产生“带有析构函数的类型不允许复制”:
impl<TNodeState> Copy for Box<dyn IConstraint<TNodeState>> {
}
克隆怎么样?我可以切换到constraints.clone_from_slice(self.constraints);
,但随后实现 Clone
IConstraint
上的特征产生一堆“IConstraint 无法成为对象”错误。
即使我可以让盒子可克隆,那么我当然会从我的 add_constraint
中得到预期的借用生命周期缺陷。方法:
borrowed value does not live long enough
所以我必须扔掉我的 add_constraint
完全使用 idea 并强制我的结构的所有者手动复制它?鉴于我的实际结构包含 3 个字段,这会变得很乏味,因为所有者现在必须将字段解构为局部变量,以便删除不可变的借用,从而允许原始向量发生突变:
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());
}
最佳答案
我认为你完全错了。正如评论中所说,您的 add_constraint
永远不会工作,因为您首先引用了在同一函数中创建的内容(该函数将在函数作用域到期后被删除)。
您应该拥有一个容器来覆盖那些 IConstraint
特征,但在里面你应该有一个 &dyn IConstraint
或Box<dyn IConstraint>
.
在这种情况下,向其中添加项目是微不足道的:
pub trait IConstraint {
// members here
}
pub struct Scenario<'a> {
pub constraints: Vec<&'a dyn IConstraint>
}
impl<'a> Scenario<'a> {
pub fn add_constraint(&mut self, constraint: &'a dyn IConstraint) {
self.constraints.push(constraint);
}
}
这应该可以解决您的问题,因为引用是 Copy
。
关于rust - 如何基于 `&[Box<dyn CustomTrait>]` 创建向量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72437343/