Rust 中是否存在组合运算符和管道转发运算符(如其他语言中(?如果是这样,它们是什么样子的,一个应该比另一个更受欢迎吗?如果不存在,为什么不需要这个运算符?
没有内置这样的运算符,但定义起来并不特别困难:
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
newtype 结构纯粹是为了允许 Shr
实例,因为否则我们将不得不在泛型(即 impl<A, B> Shr<...> for A
(,这是行不通的。
请注意,惯用的 Rust 会将其称为方法map
而不是使用运算符。有关规范示例,请参阅 Option::map
。
据我所知,这些运算符在 Rust 中不存在。到目前为止,我还没有觉得对它们有太大的需求,并且还努力保持核心 Rust 语法相当小。例如,Rust 曾经有显式的消息传递运算符,但这些运算符被删除了。
如果需要,您可以使用运算符重载来提出类似的东西,或者只是编写自己的撰写或管道转发函数。如果 Rust 团队愿意将这些包含在标准库中,我不会感到惊讶。
虽然这些运算符本身并不存在,但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())?;
实际上,Rust 确实有一个非常相似的运算符,它被称为点运算符,但它不适用于独立函数,这是唯一的主要问题。即。函数未在 IMPL! 中定义。
你可以编写像Option::map(Option::Some(1),|x| x+1)
这样的代码,这是"f(g(x("风格或使用点的代码,比如Option::Some(1).map(|x| x+1)
更f |> g(x)
样式。
点运算符允许您根据需要多次链接方法。 但是,为了使编译器作业更容易,存在限制。