假設以下函數存在:合併盒裝元素
fn merge(a1: A, a2: A) -> A { /* implemented */ }
是否有寫使用盒裝類型相同的操作功能的方法是什麼?那就是:
fn boxed_merge(a1: Box<A>, a2: Box<A>) -> Box<A> { /* ??? */ }
假設以下函數存在:合併盒裝元素
fn merge(a1: A, a2: A) -> A { /* implemented */ }
是否有寫使用盒裝類型相同的操作功能的方法是什麼?那就是:
fn boxed_merge(a1: Box<A>, a2: Box<A>) -> Box<A> { /* ??? */ }
您可以重複使用您的merge
功能,通過取消引用boxed_merge
函數內框。請注意,這不會重新使用分配,而是創建一個新的
fn boxed_merge(a1: Box<A>, a2: Box<A>) -> Box<A> {
Box::new(merge(*a1, *a2))
}
重複使用非箱子功能的好主意。 – ljedrz
您可以通過提領他們訪問的盒裝參數的內容,並在新Box
將它們結合起來。例如:
fn merge(a1: Box<usize>, a2: Box<usize>) -> Box<usize> {
Box::new(*a1 + *a2)
}
fn main() {
let a1 = Box::new(1);
let a2 = Box::new(2);
println!("{}", merge(a1, a2));
}
我主張一個由價值merge
應該不是你的基本實現。相反,變異方法提供了更多的靈活性。然後,您可以以此爲基礎通過價值和盒裝價值的方法:
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);
}
值得注意的是,這將是盒裝的情況下更有效,因爲你不必進行任何額外撥款。
這僅適用於
Copy
結構的合併。如果你有這樣的合併兩個集合,集合的元素可能不是可複製
這可能採取的價值由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);
}
我們在這裏還沒有任何額外的分配。
這僅適用於複製結構的合併。如果您有兩個合併的集合,則集合中的元素可能不可複製(例如,「Box
@ oli_obk-ker這是真的,但如果是這樣的話,我會改爲'mergenf(&mut self,other:A)',它有避免無關分配的相同好處。 – Shepmaster
你認爲'a1'和'a2'之間的合併是什麼? – ljedrz
我認爲合併爲:merge(a1:A,a2:A) - > A'。編輯我的問題,使其更清楚。 – ynimous