Rust支持使用中缀运算符作为函数吗?

时间:2017-06-13 11:15:20

标签: rust

我正在编写一个对两个数组进行分段乘法的函数。

    xs.iter()
        .zip(ys).map(|(x, y)| x * y)
        .sum()

在其他一些语言中,我可以将(*)作为函数传递给map。 Rust有这个功能吗?

3 个答案:

答案 0 :(得分:12)

NNN 的。 Sorta有点不是。

您无法将运算符编写为名称。但是大多数运算符都有特征支持,并且可以写出这些特征的名称,因此a * b实际上是Mul::mul(a, b),您可以将Mul::mul作为函数传递指针。

但在这种情况下,这并没有帮助,因为Iterator::map期待FnMut((A, B)) -> C,而二元运算符都实现FnMut(A, B) -> C

现在,你可以为此编写一个适配器,但是你需要一个适用于arity和mutability的每个组合。 你必须吃堆分配和间接需要夜间编译器。

或者,您可以在扩展特征上编写自己的Iterator::map版本,该特性为元组的迭代器接受更高的arity函数...再次,每个arity都有一个......

老实说,使用闭包更简单。

答案 1 :(得分:8)

Rust没有任何语法来传递中缀运算符,主要是因为它无论如何都是多余的。

在Rust中,每个运算符都映射到一个特征:*映射到std::ops::Mul特征,例如。

因此,直接使用*应使用std::ops::Mul::mul

xs.iter().zip(ys).map(Mul::mul).sum();

然而,有几个困难:

  1. 通常,迭代器会生成引用,而Mul是为普通值实现的,
  2. Mul::mul期望两个参数xs.zip(ys)产生一个元素(两个元素的元组)。
  3. 所以,你需要从引用转到值,然后“解包”元组,并且...最终会缩短使用闭包。

答案 2 :(得分:3)

没有。 *运算符已在std::Ops::Mul中实现,但无法直接使用:

use std::ops::Mul::mul;

fn main() {
    let v1 = vec![1, 2, 3];
    let v2 = vec![1, 2, 3];

    println!("{:?}", v1.iter().zip(v2).map(|(x, y)| mul).collect());
}

将导致以下错误:

error[E0253]: `mul` is not directly importable
 --> <anon>:1:5
  |
1 | use std::ops::Mul::mul;
  |     ^^^^^^^^^^^^^^^^^^ cannot be imported directly

您可以使用*运算符介绍自己的函数,但不会增加很多值:)。