Iterator 实现合并排序迭代器

Iterator 实现合并排序迭代器,iterator,rust,Iterator,Rust,我正在尝试实现一个迭代器,它合并了两个排序迭代器。我正在运行从结构中借用字段的问题 如何避免此错误?我尝试使用借用的引用,但似乎没有帮助,因为最终我需要移动a_项和b_项的值 使用std::num::饱和; 发布结构合并排序{ a:T, b:T, a_项目:选项, b_项目:选项, } 用于合并排序的impl迭代器{ #[内联] fn下一步(&mut self)->选项{ 匹配(self.a_项、self.b_项){ (无,无)=>无, (无,部分(y))=>{ 让结果=self.b_项; se

我正在尝试实现一个迭代器,它合并了两个排序迭代器。我正在运行从结构中借用字段的问题

如何避免此错误?我尝试使用借用的引用,但似乎没有帮助,因为最终我需要移动a_项和b_项的值

使用std::num::饱和;
发布结构合并排序{
a:T,
b:T,
a_项目:选项,
b_项目:选项,
}
用于合并排序的impl迭代器{
#[内联]
fn下一步(&mut self)->选项{
匹配(self.a_项、self.b_项){
(无,无)=>无,
(无,部分(y))=>{
让结果=self.b_项;
self.b_项目=无;
返回结果;
}
(部分(x),无)=>{
让结果=self.a_项;
self.a_item=self.a.next();
结果
}
(一些(x),一些(y))=>{
如果x(uint,选项){
//存根
(10,部分(100))
}
}
以下是具体错误,对于self.a_项和self.b_项的所有使用都会重复此错误

error: cannot move out of dereference of `&mut`-pointer
       match (self.a_item, self.b_item) {
              ^~~~~~~~~~~

第一个问题是这种模式:

let result=self.b_项目;
self.b_项目=无;
返回结果;
在第一行之后和第二行之前,
self.b_项
被移出,在
self
中打了一个“洞”(即使我们忘记了
self
是借用的指针,您也无法移出)。这是不允许的。为了表达这种模式,在
std::mem
中有一个特殊的函数,称为
replace

第二个主要问题是
A
不可隐式复制,因此当您尝试匹配
Option
类型的值时,这些值会移出,但禁止从
&/&mut
指针内部移出。解决这个问题的唯一方法是匹配引用。但是,您应该小心,因为借用规则只允许您一次使用一个可变借用。因此,您必须使用模式绑定,通过match语句组织对
self.a_项
self.b_项
的一种“流”引用

编译以下代码。您还可以使用
mem::replace()
调用直接替换
result
变量和
match
主体中的
Some()
用法,但我认为将值选择和
mem::replace()
调用分离可以使代码更干净。另外,在最后一个
匹配
臂中,我无法使用
Some(x)
Some(y)
模式,因为引用本身被移动到
a\u项
b\u项

使用std::mem;
发布结构合并排序{
a:T,
b:T,
a_项目:选项,
b_项目:选项,
}
用于合并排序的impl迭代器{
#[内联]
fn下一步(&mut self)->选项{
让结果=匹配(&mut self.a\u项,&mut self.b\u项){
(&None,&None)=>无,
(&None,b_项@&Some())=>Some((b_项,None)),
(a_item@&Some(_),&None)=>Some((a_item,self.a.next()),
(a_项目@和一些(uu),b_项目@和一些(u))=>一些(
如果a_item.get_ref()(uint,选项){
//存根
(10,部分(100))
}
}

此解决方案适用于Rust 1.2和Rust 1.x

我没有保留我们自己的
选项
,而是选择使用迭代器适配器。这使我们能够向前看一个项目,而不会丢失它

我还将
迭代器::next
方法分解为两部分-一部分决定从哪一方拉动,另一部分实际推动迭代器

还有一些关于迭代器现在如何用关联类型定义的一般更新

use std::iter::Peekable;
use std::cmp::Ordering;

struct MergeAscending<L, R>
where
    L: Iterator<Item = R::Item>,
    R: Iterator,
{
    left: Peekable<L>,
    right: Peekable<R>,
}

impl<L, R> MergeAscending<L, R>
where
    L: Iterator<Item = R::Item>,
    R: Iterator,
{
    fn new(left: L, right: R) -> Self {
        MergeAscending {
            left: left.peekable(),
            right: right.peekable(),
        }
    }
}

impl<L, R> Iterator for MergeAscending<L, R>
where
    L: Iterator<Item = R::Item>,
    R: Iterator,
    L::Item: Ord,
{
    type Item = L::Item;

    fn next(&mut self) -> Option<L::Item> {
        let which = match (self.left.peek(), self.right.peek()) {
            (Some(l), Some(r)) => Some(l.cmp(r)),
            (Some(_), None) => Some(Ordering::Less),
            (None, Some(_)) => Some(Ordering::Greater),
            (None, None) => None,
        };

        match which {
            Some(Ordering::Less) => self.left.next(),
            Some(Ordering::Equal) => self.left.next(),
            Some(Ordering::Greater) => self.right.next(),
            None => None,
        }
    }
}

fn main() {
    let left = [1, 3, 5, 7, 9];
    let right = [3, 4, 5, 6, 7];

    let result: Vec<_> = MergeAscending::new(left.iter(), right.iter()).collect();
    println!("{:?}", result);
}
使用std::iter::Peekable;
使用std::cmp::Ordering;
结构合并
哪里
L:迭代器,
R:迭代器,
{
左:可偷看,
右:可偷看,
}
impl合并
哪里
L:迭代器,
R:迭代器,
{
fn新(左:左,右:右)->Self{
合并上升{
left:left.peek(),
right:right.peek(),
}
}
}
用于合并的impl迭代器
哪里
L:迭代器,
R:迭代器,
项目:作战需求文件,
{
类型Item=L::Item;
fn下一步(&mut self)->选项{
让which=匹配(self.left.peek(),self.right.peek()){
(一些(l),一些(r))=>一些(l.cmp(r)),
(一些(41;,无)=>一些(排序::更少),
(无,一些())=>一些(排序::更大),
(无,无)=>无,
};
匹配哪个{
Some(Ordering::Less)=>self.left.next(),
Some(Ordering::Equal)=>self.left.next(),
Some(Ordering::Greater)=>self.right.next(),
无=>无,
}
}
}
fn main(){
left=[1,3,5,7,9];
让右=[3,4,5,6,7];
let result:Vec=MergeAscending::new(left.iter(),right.iter()).collect();
println!(“{:?}”,结果);
}

谢谢你的深入解释,这比我想象的要复杂得多。
一些((b_项,无))
不应该是
一些((b_项,self.b.next())
?否则,我们将自动放弃
b
中的所有后续元素。(无论如何,这是一个非常好的方法。+1)@