如何设置这些结构的生命周期?
How to set the lifetime on these structures?
我正在尝试制作一个迭代器,它从移动列表中过滤掉某些移动。为了不拥有返回的移动的所有权,它们被引用。但是,这样做时会出现 missing lifetime specifier
编译器错误。由于我有一个结构链,我认为解决问题的第一步是开始将生命周期放在 MoveFilter
上,然后放在 IntoIterator
中的 type Item
上。然而,它抱怨使用未声明的生命周期。
代码:
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<'a> {
legal_moves: Vec<GameMove>,
move_type: GameMoveType,
}
impl IntoIterator for MoveFilter {
type Item = &'a GameMove;
type IntoIter = MoveFilterIterator;
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 {
legal_moves: Vec<GameMove>,
move_type: usize,
index: usize,
}
impl Iterator for MoveFilterIterator {
type Item = &GameMove;
fn next(&mut self) -> Option<&GameMove> {
while self.index < self.legal_moves.len() {
if match_move_type(&self.legal_moves[self.index].move_type) == self.move_type {
Some(&self.legal_moves[self.index])
} else {
self.index += 1;
}
}
None
}
}
您的
取得 MoveFilter
所有权的方法 fn into_iter(self: MoveFilter)
和
方法 fn next(&mut self) -> Option<&GameMove>
只想分发对 GameMove
的不可变引用。在您的 into_iter
获得 MoveFilter
的所有权并完全使用它之后,谁应该拥有引用的 GameMove
?
解决它的一种方法是为 &'a MoveFilter
实现 IntoIterator
,它不会取得 MoveFilter
的所有权,因此不必担心所有 [=14] =]s 在有任何引用 &'a GameMove
浮动时被丢弃:
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
-loop 在那里做什么。
我正在尝试制作一个迭代器,它从移动列表中过滤掉某些移动。为了不拥有返回的移动的所有权,它们被引用。但是,这样做时会出现 missing lifetime specifier
编译器错误。由于我有一个结构链,我认为解决问题的第一步是开始将生命周期放在 MoveFilter
上,然后放在 IntoIterator
中的 type Item
上。然而,它抱怨使用未声明的生命周期。
代码:
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<'a> {
legal_moves: Vec<GameMove>,
move_type: GameMoveType,
}
impl IntoIterator for MoveFilter {
type Item = &'a GameMove;
type IntoIter = MoveFilterIterator;
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 {
legal_moves: Vec<GameMove>,
move_type: usize,
index: usize,
}
impl Iterator for MoveFilterIterator {
type Item = &GameMove;
fn next(&mut self) -> Option<&GameMove> {
while self.index < self.legal_moves.len() {
if match_move_type(&self.legal_moves[self.index].move_type) == self.move_type {
Some(&self.legal_moves[self.index])
} else {
self.index += 1;
}
}
None
}
}
您的
取得 MoveFilter
所有权的方法 fn into_iter(self: MoveFilter)
和
方法 fn next(&mut self) -> Option<&GameMove>
只想分发对 GameMove
的不可变引用。在您的 into_iter
获得 MoveFilter
的所有权并完全使用它之后,谁应该拥有引用的 GameMove
?
解决它的一种方法是为 &'a MoveFilter
实现 IntoIterator
,它不会取得 MoveFilter
的所有权,因此不必担心所有 [=14] =]s 在有任何引用 &'a GameMove
浮动时被丢弃:
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
-loop 在那里做什么。