假设存在以下函数:
fn merge(a1: A, a2: A) -> A { /* implemented */ }
有没有办法使用盒装类型为相同的操作编写函数?即:
fn boxed_merge(a1: Box<A>, a2: Box<A>) -> Box<A> { /* ??? */ }
最佳答案
我提倡按值 merge
应该不作为您的基本实现。相反,变异方法提供了更大的灵 active 。然后,您可以在此基础上构建按值和按装箱值方法:
struct A(u8);
impl A {
fn merge_ref(&mut self, other: &A) {
self.0 += other.0
}
}
fn merge(mut a1: A, a2: A) -> A {
a1.merge_ref(&a2);
a1
}
fn boxed_merge(mut a1: Box<A>, a2: Box<A>) -> Box<A> {
a1.merge_ref(&a2);
a1
}
fn main() {
let a1 = A(1);
let a2 = A(2);
let a3 = merge(a1, a2);
let boxed_a3 = Box::new(a3);
let boxed_a4 = Box::new(A(4));
let boxed_a7 = boxed_merge(boxed_a3, boxed_a4);
println!("{}", boxed_a7.0);
}
值得注意的是,这在盒装情况下会更有效,因为您不必执行任何额外的分配。
This only applies for merges of
Copy
structures. If you had two sets that are merged, the elements of the set might not be copyable
这可以通过在 merge_ref
中按值合并并使用相同的技巧在 boxed_merge
方法中移出盒子来解决:
struct B(Vec<u8>);
impl B {
fn merge_ref(&mut self, other: B) {
self.0.extend(other.0)
}
}
fn merge(mut b1: B, b2: B) -> B {
b1.merge_ref(b2);
b1
}
fn boxed_merge(mut b1: Box<B>, b2: Box<B>) -> Box<B> {
b1.merge_ref(*b2);
b1
}
fn main() {
let b1 = B(vec![1]);
let b2 = B(vec![2]);
let b3 = merge(b1, b2);
let boxed_b3 = Box::new(b3);
let boxed_b4 = Box::new(B(vec![4]));
let boxed_b7 = boxed_merge(boxed_b3, boxed_b4);
println!("{:?}", boxed_b7.0);
}
我们这里仍然没有任何额外的分配。
关于rust - 合并盒装元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44018378/