如果传递谓词则返回值,否则为默认值

时间:2016-12-29 17:36:41

标签: rust optional predicate

如果谓词失败,如何替换值?

举例说明:

assert_eq!((3-5).but_if(|v| v < 0).then(0), 0)

我认为OptionResult会有这样的内容,但我无法找到它。

2 个答案:

答案 0 :(得分:5)

  

我认为Resultfn main() { let a = 3 - 5; assert_eq!(if a < 0 { 0 } else { a }, 0); }

会有一些内容

但这些类型都不会出现在这里。减去两个数字会产生另一个数字。

看起来你只想要一个传统的if-else语句:

max

由于您有两个可以比较的值,您可能还对use std::cmp::max; fn main() { assert_eq!(max(0, 3 - 5), 0); }

感兴趣
fn main() {
    assert_eq!((3 - 5).but_if(|&v| v < 0).then(0), 0)
}

trait ButIf: Sized {
    fn but_if<F>(self, f: F) -> ButIfTail<Self>
        where F: FnOnce(&Self) -> bool;
}

// or `impl<T> ButIf for T {` for maximum flexibility
impl ButIf for i32 {
    fn but_if<F>(self, f: F) -> ButIfTail<Self>
        where F: FnOnce(&Self) -> bool,
    {
        ButIfTail(f(&self), self)
    }
}

struct ButIfTail<T>(bool, T);

impl<T> ButIfTail<T> {
    fn then(self, alt: T) -> T {
        if self.0 {
            alt
        } else {
            self.1
        }
    }
}

可以使你提出的语法有效,但我不确定它是否值得。提交时没有进一步评论......

{{1}}

答案 1 :(得分:3)

更新:自Rust 1.27 {@ 3}}添加Option::filter以来,这有点好了:

assert_eq!(Some(3 - 5).filter(|&v| v >= 0).unwrap_or(0), 0);

在Rust 1.27之前,你需要一个迭代器来编写一个单独的链式表达式而不需要额外的自定义机制:

assert_eq!(Some(3 - 5).into_iter().filter(|&v| v >= 0).next().unwrap_or(0), 0);