rust - 解决多个 bool 表达式的最佳/惯用方法是什么?

标签 rust boolean-expression

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.

去年关闭。




Improve this question




我必须执行多个 bool 运算,不是很复杂但很长,当我试图获得最好的可读性和可理解的结果时,我想出了多种解决方案,我不确定什么是“正确的”(惯用?) 方法。
我不确定是否有“正确”的答案,因为它可能是主观的,如果 X 更喜欢这种方式,我不会感兴趣,但我相信关于优化或惯用方式,有错误的答案或更好的答案。或者应该如何使用该功能,以及在哪种情况下。
目标:

pub struct Coord {
    x: i32,
    y: i32
}

impl Coord {
    pub fn is_connected(&self, coord: &Coord) -> bool {}
}

调用 self 值 x1 和 y1,以及坐标值 x2 和 y2,is_connected 的结果将在以下情况下为真:x1 == x2 and either y2 == y+1 or y2 == y-1或者有一条线的条件已经完成


x2
y2
y<6
y%2


x+1
y+1
真的
0

x-1
y-1
真的
1

x-1
y+1
错误的
0

x+1
y-1
错误的
1


原始的 bool 链式解决方案如下所示:
pub fn is_connected2(&self, coord: &Coord) -> bool {
    coord.x == self.x && (coord.y == self.y+1 || coord.y == self.y-1)
        || (self.y < 6
            && ((self.y % 2 == 0 && coord.x == self.x+1 && coord.y == self.y+1)
                || (self.y % 2 == 1 && coord.x == self.x-1 && coord.y == self.y-1)))
        || (self.y > 6
            && ((self.y % 2 == 0 && coord.x == self.x-1 && coord.y == self.y+1)
                || (self.y % 2 == 1 && coord.x == self.x+1 && coord.y == self.y-1)))
}
我相信它有点难以阅读。
就像这个很棒的功能一样使用rust ,比赛,我想使用它,特别是因为我还在测试它。但是我完全忘记了你不能(据我所知)将变量值放在 ARM 中,而必须将它们添加到后卫中,这使得比赛看起来比我最初想要的要大得多(我在想一个match (self, road) 并在比赛中做 ((x,y),(x+1,y+1)) 之类的事情)。
因此,虽然我认为比赛更清晰,但我不确定这两个选项中的一个是否更好(因为一个在守卫中拥有一切,另一个在模式中,我不知道哪个更好/更多惯用语)。我还将表达式的其余部分放在结果中,而我也可以将它放在守卫中。但是有这么多选择让我相信其中一些选择将是“防 rust ”,因为以非预期或非惯用的方式使用该功能。
pub fn is_connected(&self, coord: &Coord) -> bool {
    coord.x == self.x && (coord.y == self.y+1 || coord.y == self.y-1)
        || match self.y {
            _ if self.y < 6 && self.y % 2 == 0 => {coord.x == self.x+1 && coord.y == self.y+1},
            _ if self.y < 6 && self.y % 2 == 1 => {coord.x == self.x-1 && coord.y == self.y-1},
            _ if self.y > 6 && self.y % 2 == 0 => {coord.x == self.x-1 && coord.y == self.y+1},
            _ if self.y > 6 && self.y % 2 == 1 => {coord.x == self.x+1 && coord.y == self.y-1}, 
            _ => false
        }
}

pub fn is_connected_bis(&self, coord: &Coord) -> bool {
    coord.x == self.x && (coord.y == self.y+1 || coord.y == self.y-1)
        || match (self.y < 6, self.y%2) {
            (true, 0) => {coord.x == self.x+1 && coord.y == self.y+1}, 
            (true, 1) => {coord.x == self.x-1 && coord.y == self.y-1}, 
            (false, 0) => {coord.x == self.x-1 && coord.y == self.y+1},
            (false, 1) => {coord.x == self.x+1 && coord.y == self.y-1}, 
            _ => false
        }    
}

pub fn is_connected4(&self, coord: &Coord) -> bool {
    // bis would be to take the y<6 and y%2 in the guard as well
    match (self.y<6, self.y%2) {
        (_,_) if coord.x == self.x && coord.y == self.y+1 => true,
        (_,_) if coord.x == self.x && coord.y == self.y-1 => true,
        (true, 0) if coord.x == self.x+1 && coord.y == self.y+1 => true,
        (true, 1) if coord.x == self.x-1 && coord.y == self.y-1 => true,
        (false, 0) if coord.x == self.x-1 && coord.y == self.y+1 => true,
        (false, 1) if coord.x == self.x+1 && coord.y == self.y-1 => true,
        _ => false
    } 
}
还有一种老式的 if 方式:
pub fn is_connected3(&self, coord: &Coord) -> bool {
    let res: bool = coord.x == self.x && (coord.y == self.y+1 || coord.y == self.y-1);
    res ||
    // or if res {} else {}... 
        if self.y < 6 {
            if self.y % 2 == 0 {
                coord.x == self.x+1 && coord.y == self.y+1
            } else {
                coord.x == self.x-1 && coord.y == self.y-1
            }
        } else {
            if self.y % 2 == 0 {
                coord.x == self.x-1 && coord.y == self.y+1
            } else {
                coord.x == self.x+1 && coord.y == self.y-1
            }
        }
}
我不得不承认,在我完全意识到后卫应该是什么之前,我的问题最初是由如何在比赛条件下进行变量激发的。我的问题后来演变了,但仍然有一些原始的痕迹与所有匹配表达式。
我特别好奇我写的某些匹配是否“糟糕”,不是主观/如何正确阅读,而是关于如何设计 rust 以及如何使用功能。

最佳答案

bool 表达式很酷的一点是,它们经常可以被简化。我还没有测试下一个代码,但我希望它与您显示的表格等效。

pub fn is_connected(&self, coord: &Coord) -> bool {
    let is_y_even = (self.y % 2 == 0);
    let adjusted_x = if (self.y < 6) == is_y_even { self.x+1 } else { self.x-1 };
    let adjusted_y = if is_y_even { self.y+1 } else { self.y-1 };
    adjusted_x == coord.x && adjusted_y == coord.y
}

关于rust - 解决多个 bool 表达式的最佳/惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65955820/

相关文章:

logic - 如何理解这种风格的K-map

while 循环中的 bool (标量)上下文中的 Perl 列表

javascript - bool 值到整数的转换

c++ - bool 表达式中带有 strlen() 的奇怪行为

functional-programming - 如何在 Rust 中不那么命令式地重写它

iterator - 如何跳过 Rust 中迭代器的前 n 项?

rust - 调用 Option::map 后如何使用值?

java - 如何将由多个AND、OR组成的If语句转换为switch语句?

performance - 与其他系统编程语言(如 C)中通常使用的函数相比,Rust 风格的方法调用方法是否有任何开销?

rust - 手动删除引用包装器的Rust生命周期问题