24

Rust中是否同时存在组合和管道前向运算符(就像其他语言中一样)?如果是这样,它们看起来像什么,应该一个比另一个更喜欢?如果不存在,为什么不需要此运算符?

4

4 回答 4

27

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

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典型示例。

于 2013-06-14T15:08:22.830 回答
4

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

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

于 2013-06-12T17:11:22.467 回答
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())?;
于 2020-01-14T18:00:56.890 回答
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)样式更多。

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

于 2021-05-15T07:09:27.770 回答