mte*_*eXD 0 mergesort rust borrow-checker
我正在尝试在 Rust 中实现合并排序的合并功能。问题是我试图为泛型类型执行此操作T,该类型仅受std::cmp::PartialOrd.
这是代码:
fn my_merge<T: std::cmp::PartialOrd>(a: &mut Vec<T>, mut b: &mut Vec<T>) -> Vec<T> {
let mut res: Vec<T> = Vec::new();
let mut a_iter = a.into_iter(); // !!!
let mut b_iter = b.into_iter(); // !!!
while let (Some(a_item), Some(b_iter)) = (a_iter.next(), b_iter.next()) {
if a_item <= b_item {
res.push(*a_item); // !!!
} else {
res.push(*b_item); // !!!
}
}
// ... Omitted code ...
res
}
Run Code Online (Sandbox Code Playgroud)
在查看文档时,我发现了该into_iter()方法,该next()方法应该产生T而不是&T. 但只有当迭代器不是在引用上构造时,它才会这样做(因为我将切片传递到函数中)。(快速提醒:这是因为借用的工作方式。请参阅此 StackOverflow 问题)
这与不能取消引用变量a_item和b_item带注释的行的原因相同。
我的问题是:有没有办法在保持泛型类型的同时解决这个问题?这几乎是自相矛盾的,因为理论上这是一项非常简单的任务 - “只需将元素的所有权从一个向量移动到另一个向量” - 但由于所有权规则,这并不那么简单。
您可以使用以下方法迭代一段Vec时间,声明元素的所有权,而无需消耗原始元素本身:Vec.drain(..)
fn my_merge<T: std::cmp::PartialOrd>(a: &mut Vec<T>, b: &mut Vec<T>) -> Vec<T> {
let mut res: Vec<T> = Vec::new();
let mut a_iter = a.drain(..);
let mut b_iter = b.drain(..);
while let (Some(a_item), Some(b_item)) = (a_iter.next(), b_iter.next()) {
if a_item <= b_item {
res.push(a_item);
} else {
res.push(b_item);
}
}
res
}
Run Code Online (Sandbox Code Playgroud)
这当然会使输入 (a和b) 为空,但在合并后仍保留其原始容量。
| 归档时间: |
|
| 查看次数: |
44 次 |
| 最近记录: |