Rust中的合成运算符和管道转发运算符

时间:2013-06-11 22:34:32

标签: rust

Rust中是否存在组合和管道转发操作符(like in other languages)?如果是这样,它们看起来像什么,而另一个应该优先考虑?如果不存在,为什么不需要这个操作符?

4 个答案:

答案 0 :(得分:23)

内置没有这样的运算符,但定义起来并不是特别困难:

use std::ops::Shr;

struct Wrapped<T>(T);

impl<A, B, F> Shr<F> for Wrapped<A>
    where F: FnOnce(A) -> B
{
    type Output = Wrapped<B>;

    fn shr(self, f: F) -> Wrapped<B> {
        Wrapped(f(self.0))
    }
}

fn main() {
    let string = Wrapped(1) >> (|x| x + 1) >> (|x| 2 * x) >> (|x: i32| x.to_string());
    println!("{}", string.0);
}
// prints `4`

Wrapped新类型结构纯粹是为了允许Shr实例,否则我们必须在泛型(即impl<A, B> Shr<...> for A)上实现它,这不起作用


请注意,惯用Rust会将此方法称为map,而不是使用运算符。有关规范示例,请参阅Option::map

答案 1 :(得分:3)

据我所知,这些运算符在Rust中不存在。到目前为止,我并没有对它们感到太多需求,并且还努力保持核心Rust语法相当小。例如,Rust曾经有过显式的消息传递操作符,但这些操作符被删除了。

如果需要,您可以使用运算符重载来提供类似的东西,或者只编写自己的compose或pipe forward函数。如果Rust团队愿意将这些内容包含在标准库中,我不会感到惊讶。

答案 2 :(得分:3)

虽然这些运算符不是一个人存在,但是Option::map提供了惯用的类比。

fn do_some_stuff_to_a_number(x: Option<i32>) -> Option<String> {
    x.map(|x| x + 1).map(|x| 2 * x).map(|x: i32| x.to_string())
}

并且没有功能:

let string = Some(1)
    .map(|x| x + 1)
    .map(|x| 2 * x)
    .map(|x: i32| x.to_string())?;

答案 3 :(得分:0)

实际上,rust 确实有一个非常相似的运算符,它被称为点运算符,但是它不适用于独立函数,这是唯一的主要问题。 IE。未在 impl 中定义的函数!

您可以编写像 Option::map(Option::Some(1),|x| x+1) 这样的代码,它是 'f(g(x)' 样式或使用点的代码,例如 Option::Some(1).map(|x| x+1),它更像 f |> g(x) 样式。

点运算符允许您根据需要多次链接方法。然而,使编译器工作更容易是有限制的。