我有一块黑板,我可以用glam::IVec2分来索引.

struct Board{pieces: [char;64]}
type PieceOption = Option<char>;

这块板的指数方法是

impl Index<IVec2> for Board {
    type Output = PieceOption;
    fn index(&self, v : IVec2) -> &Self::Output{
        if (v.abs() != v) || (v.max_element() > 8) {&None}
        else {
            let i : usize = (v.x + 8* v.y).try_into().unwrap();
            &Some(self.pieces[i])
        }
    }
}

除了这个,PieceOption还有方法is_empty,is_allyis_rival,所以我的问题是:这个递归函数的值应该是什么,为了实现类型一致性,我需要该函数返回一个向量,但我不想在下一块是相同 colored颜色 (Is_Ally)的情况下返回该向量.除此之外,我想知道是否有一种方法可以解包Some个值,这样我就不需要为Match语句中的每个分支键入一些(‘char’),特别是因为我已经过滤了下一步超出界限的情况.这是类型不一致的当前函数.这是目前为主教们实现的功能,我的目的是为每种运动类型提供此功能.

const DIAGONALS : [IVec2; 4] = [
    ivec2(-1, -1), ivec2(-1, 1),
    ivec2(-1, 1), ivec2(1, 1)
];

下面是该函数的当前状态

impl Board {
    fn moves(&self, piece:&PieceOption, pos:IVec2, dir: Vec<IVec2>)->Vec<IVec2>{
        dir.into_iter()
            .map(|d| d+pos)
            .filter(|p| (p.abs() == *p) && p.max_element() < 8)
            .flat_map(|p|
                match piece{
                    Some('B')|Some('b')=>{
                        if self[p].is_empty() {self.moves(piece, p, vec![p-pos]).push(p)}
                        else if self[p].is_rival(*piece) {p}
                        else {()} /* here is where i do not wish to return a vector because
 this is likely a case where the next piece is an opponent*/
                        },
                    _ => () /* here is where i  do not wish to return a vector because 
the piece is likely empty space*/
                }
            )
            .collect()
    }
}

最新情况: UPDATE我已经意识到我需要if let来解开片段的选项,但是我真的不知道If let语句的返回值应该是什么,我当前函数的代码是

impl Board {
    fn moves(&self, piece:&PieceOption, pos:IVec2, dir: Vec<IVec2>)->Option<Vec<IVec2>>{
        dir.into_iter()
            .map(|d| d+pos)
            .filter(|p| (p.abs() == *p) && p.max_element() < 8)
            .flat_map(|p|
                if let Some(c) = piece{
                    match c{
                        'B'|'b'=>{
                            if self[p].is_empty() {self.moves(piece, p, vec![p-pos])?.push(p)}
                            else if self[p].is_rival(*piece) {Some(vec![p])}
                            else {None?}
                            },
                        _ => None
                        }
                } else {None}   
            )
            .collect()
    }
}

此外,我非常感谢任何关于格式的建议,我想知道人们对这个潜在的解决方案的看法,如果这个问题措辞混乱,我会道歉吗? 完整代码可在以下位置找到: https://github.com/LyndonAlcock/chess_test

推荐答案

传递给flat_map的闭包的返回类型应该是集合. 如果您不想添加任何内容,只需返回一个空的.在Vec的情况下为vec![]

另外,Option<char>是副本,所以你可以只传递一个东西,而不是一个参考.

impl Board {
    fn moves(&self, piece: PieceOption, pos: IVec2, dir: Vec<IVec2>) -> Vec<IVec2> {
        dir.into_iter()
            .map(|d| d+pos)
            .filter(|p| (p.abs() == *p) && p.max_element() < 8)
            .flat_map(|p|
                if let Some(c) = piece {
                    match c {
                        'B'|'b'=> {
                            if self[p].is_empty() {
                                let moves = self.moves(piece, p, vec![p-pos])
                                moves.push(p);
                                moves
                            } else if self[p].is_rival(*piece) {
                                vec![p]
                            } else {
                                vec![]
                            }
                        },
                        _ => vec![]
                        }
                } else {
                    vec![]
                }
            )
            .collect()
    }
}

Rust相关问答推荐

如何从polars DataFrame中获取一个列作为Option String?<>

为什么我需要在这个代码示例中使用&

什么是Rust惯用的方式来使特征向量具有单个向量项的别名?

通过使用光标拖动角来绕其中心旋转矩形

如何正确地将App handler传递给Tauri中的其他模块?

为昂贵的for循环制作筛子

RUST应用程序正在退出,错误代码为:(退出代码:0xc0000005,STATUS_ACCESS_VIOLATION)

在Rust中判断编译时是否无法访问

如何执行数组文字的编译时串联?

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

Rust 异步循环函数阻塞了其他future 任务的执行

如何在 Rust 的 Hyper 异步闭包中从外部范围正确读取字符串值

如何限制通用 const 参数中允许的值?

从 HashMap>, _> 中删除的生命周期问题

如果不满足条件,如何在 Rust 中引发错误

bcrypt 有长度限制吗?

如何展平以下嵌套的 if let 和 if 语句?

如果我不想运行析构函数,如何移出具有析构函数的 struct ?

你能用 Rust 和 winapi 制作 Windows 桌面应用程序吗?

如何在不设置精度的情况下打印浮点数时保持尾随零?