我正在尝试实现一个合并两个排序的迭代器的迭代器。我正在尝试从结构中借用字段的问题。
如何避免此错误?我尝试使用借用的引用,但这似乎无济于事,因为最终我需要移动a_item和b_item的值。
use std::num::Saturating;
pub struct MergeSorted<A, T> {
a: T,
b: T,
a_item: Option<A>,
b_item: Option<A>,
}
impl<A: Ord, T: Iterator<A>> Iterator<A> for MergeSorted<A, T> {
#[inline]
fn next(&mut self) -> Option<A> {
match (self.a_item, self.b_item) {
(None, None) => None,
(None, Some(y)) => {
let result = self.b_item;
self.b_item = None;
return result;
}
(Some(x), None) => {
let result = self.a_item;
self.a_item = self.a.next();
result
}
(Some(x), Some(y)) => {
if x < y {
let result = self.a_item;
self.a_item = self.a.next();
result
} else {
let result = self.b_item;
self.b_item = self.b.next();
result
}
}
}
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
// stub
(10, Some(100))
}
}
这是特定的错误,对于self.a_item和self.b_item的所有使用都会重复此错误。
error: cannot move out of dereference of `&mut`-pointer
match (self.a_item, self.b_item) {
^~~~~~~~~~~
第一个问题是这种模式:
let result = self.b_item;
self.b_item = None;
return result;
在第一行之后和第二行self.b_item
被移出之前,在其中打个“洞” self
(即使我们忘记这self
是借来的指针,也不能移出它)。这是不允许的。为了表达这种模式,有一个特殊的功能std::mem
称为replace
。
第二个主要问题是A
不可隐式复制,因此,当您尝试匹配type的值时Option<A>
,这些值将移出,但&/&mut
禁止从指针内部移出。解决此问题的唯一方法是匹配引用。但是您应该小心,因为借阅规则仅允许您一次只能进行一次可变的借阅。所以,你必须组织一种参考的“流”到self.a_item
,并self.b_item
通过匹配语句,使用模式绑定。
以下代码进行编译。您也可以直接用调用替换主体中的result
变量和Some()
用法,但是我认为将值选择和调用分开可以使代码更简洁。我也不能在最后一臂中使用和模式,因为引用本身已移入和。match
mem::replace()
mem::replace()
Some(x)
Some(y)
match
a_item
b_item
use std::mem;
pub struct MergeSorted<A, T> {
a: T,
b: T,
a_item: Option<A>,
b_item: Option<A>,
}
impl<A: Ord, T: Iterator<A>> Iterator<A> for MergeSorted<A, T> {
#[inline]
fn next(&mut self) -> Option<A> {
let result = match (&mut self.a_item, &mut self.b_item) {
(&None, &None) => None,
(&None, b_item @ &Some(_)) => Some((b_item, None)),
(a_item @ &Some(_), &None) => Some((a_item, self.a.next())),
(a_item @ &Some(_), b_item @ &Some(_)) => Some(
if a_item.get_ref() < b_item.get_ref() {
(a_item, self.a.next())
} else {
(b_item, self.b.next())
}
)
};
result.and_then(|(dest, value)| mem::replace(dest, value))
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
// stub
(10, Some(100))
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句