微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以使用“ impl Fn”特征在Rust中实现多级currying函数吗?

如何解决我可以使用“ impl Fn”特征在Rust中实现多级currying函数吗?

我尝试实现类似于Functional Programming Jargon in Rust的易变功能,该功能引入了以下代码

fn add_origin(x: i32) -> impl Fn(i32) -> i32 {
    return move |y| {
        x + y
    };
}

fn main() {
    let add5 = add_origin(5);
    println!("Call closure: {}",add5(6));
}

这可行,然后我想添加一个级别,如:

fn add(x: i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 {
    return move |y: i32| {
        return move |z: i32| {
            x + y + z
        }
    };
}

fn main() {
    let add5 = add(5);
    let add5_10 = add5(10);
    println!("Call closure: {}",add5_10(6));
}

编译器不接受此代码并告诉我:

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
 --> src/main.rs:7:35
  |
7 | fn add(x: i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 {
  |                                   ^^^^^^^^^^^^^^^^^^^

error: aborting due to prevIoUs error

为什么不能通过此代码?还是我做错了方法

解决方法

impl Trait语法只能在函数签名的参数位置或返回位置使用。两者都很好:

fn takes_fn(fn_arg: impl Fn(i32) -> i32) {}

fn returns_fn() -> impl Fn(i32) -> i32 {
  |x| x
}

但是这些都不起作用:

fn takes_fn(fn_arg: impl Fn(i32) -> impl Fn(i32) -> i32) {}

fn returns_fn() -> impl Fn(i32) -> impl Fn(i32) -> i32 {
  |x| x
}

因为第二个嵌套的impl Trait不再位于参数或返回位置,但现在已成为参数或返回类型签名的一部分,这是不允许的。基本上,无论您将impl Trait嵌套在什么位置,都将永远无法工作,并且始终会出现相同的编译错误。

好消息是这不会阻止您完成要完成的工作,因为impl Trait只是语法糖,它的使用是可选的。在您的特定示例中,我们可以使用装箱的特征对象返回您的咖喱函数。

fn add(x: i32) -> impl Fn(i32) -> Box<dyn Fn(i32) -> i32> {
    move |y: i32| {
        Box::new(move |z: i32| {
            x + y + z
        })
    }
}

fn main() {
    let add5 = add(5);
    let add5_10 = add5(10);
    println!("Call closure: {}",add5_10(6)); // prints "Call closure: 21"
}

playground

另请参阅:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。