我试图实现一个合并两个已排序迭代器的迭代器。我正在运行从结构中发布借用字段。
如何避免此错误?我尝试使用借用的引用,但这似乎没有帮助,因为最终我需要移动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) {
^~~~~~~~~~~
答案 0 :(得分:5)
第一个问题是这种模式:
let result = self.b_item;
self.b_item = None;
return result;
在第一行之后和第二行self.b_item
移出之前,在self
中形成一个“洞”(即使我们忘记了self
是一个借来的指针,你可以不要离开它。这是不允许的。为了表达这种模式,std::mem
中有一个特殊功能,称为replace
。
第二个主要问题是A
不可隐式复制,因此当您尝试匹配类型Option<A>
的值时,这些值会被移出,但会从{ {1}}指针被禁止。解决这个问题的唯一方法是匹配引用。但是那时你应该小心,因为借用规则只允许你一次有单一的可变借款。因此,您必须使用模式绑定通过匹配语句组织一种对&/&mut
和self.a_item
的引用“流”。
以下代码编译。您还可以使用self.b_item
调用直接替换result
正文中的Some()
变量和match
用法,但我认为分隔值选择和mem::replace()
调用make代码清理器。另外,我在上一个mem::replace()
手臂中无法使用Some(x)
和Some(y)
模式,因为引用本身已移至match
和a_item
。
b_item