我正在尝试制作一个迭代器,该迭代器从移动列表中过滤掉某些移动。为了不拥有返回的移动的所有权,它们被引用。但是,这样做时,会出现missing lifetime specifier
编译器错误。由于我拥有一系列结构,因此我认为解决该问题的第一步是开始将生存期放在MoveFilter
上,然后放在type Item
的{{1}}上。但是,它在那里抱怨使用了未声明的生命周期。
代码:
IntoIterator
答案 0 :(得分:2)
您的之间存在差异
拥有fn into_iter(self: MoveFilter)
所有权的方法MoveFilter
和
方法fn next(&mut self) -> Option<&GameMove>
只希望分发对GameMove
的不可变引用。在您的GameMove
拥有into_iter
的所有权并完全消耗掉之后,谁应该拥有引用的MoveFilter
?
解决此问题的一种方法是为IntoIterator
实现&'a MoveFilter
,因为它不需要拥有MoveFilter
的所有权,因此不必担心所有GameMove
当周围有任何引用&'a GameMove
时,s被丢弃:
pub struct GameMove {
pub from: usize,
pub to: usize,
pub move_type: GameMoveType,
pub piece_type: PieceType,
}
#[derive(PartialEq, Clone, Debug)]
pub enum GameMoveType {
Quiet,
Capture(PieceType),
}
#[derive(PartialEq, Clone, Debug)]
pub enum PieceType {
King,
Pawn
}
pub fn match_move_type(move_type: &GameMoveType) -> usize {
match move_type {
GameMoveType::Quiet => 0,
GameMoveType::Capture(_) => 1,
}
}
pub struct MoveFilter {
legal_moves: Vec<GameMove>,
move_type: GameMoveType,
}
impl<'t> IntoIterator for &'t MoveFilter {
type Item = &'t GameMove;
type IntoIter = MoveFilterIterator<'t>;
fn into_iter(self) -> Self::IntoIter {
MoveFilterIterator {
legal_moves: &self.legal_moves[..],
move_type: match_move_type(&self.move_type),
index: 0,
}
}
}
pub struct MoveFilterIterator<'a> {
legal_moves: &'a [GameMove],
move_type: usize,
index: usize,
}
impl<'a> Iterator for MoveFilterIterator<'a> {
type Item = &'a GameMove;
fn next(&mut self) -> Option<&'a GameMove> {
while self.index < self.legal_moves.len() {
if match_move_type(&self.legal_moves[self.index].move_type) == self.move_type {
return Some(&self.legal_moves[self.index])
} else {
self.index += 1;
}
}
None
}
}
另一种可能的解决方案是将您的IntoIterator for MoveFilter
保持原样,然后将Item = &GameMove
更改为Item = GameMove
。这将为您提供一个破坏性的迭代器,该迭代器可以移动MoveFilter
,并且只能使用一次,但是我认为这并不是从type Item = &GameMove
开始时想要的。实现它似乎有点尴尬,因为从向量中删除单个元素并不完全简单,而且我不太了解while
循环在那里所做的事情。