Iterator 实现合并排序迭代器
我正在尝试实现一个迭代器,它合并了两个排序迭代器。我正在运行从结构中借用字段的问题 如何避免此错误?我尝试使用借用的引用,但似乎没有帮助,因为最终我需要移动a_项和b_项的值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
使用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)@