【问题标题】:How to create a sized closure or implement Fn/FnMut/FnOnce on a struct?如何在结构上创建一个大小合适的闭包或实现 Fn/FnMut/FnOnce?
【发布时间】:2015-04-10 05:13:16
【问题描述】:

基本上,我想编写一个返回闭包的函数。我怎样才能做到这一点而不必返回Box<FnOnce(u32)>

closures chapter of the rust book 中,我读到闭包只是结构的语法糖和FnOnce 的实现。这是我的尝试:

#[derive(Debug)]
struct MyError {
    code: u32,
    location: &'static str,
}
// Here is my closure:
struct MyErrorPartial {
    location: &'static str,
}
impl FnOnce(u32) for MyErrorPartial {
    type Output = MyError;

    fn call_once(self, args: u32) -> MyError {
        MyError {
            code: args,
            location: self.location,
        }
    }
}
fn error_at(location: &'static str) -> MyErrorPartial {
    MyErrorPartial {location: location}
}

fn function_returning_code() -> Result<(), u32> {
    Err(123)
}
fn function_with_error() -> Result<(), MyError> {
    try!(function_returning_code().map_err(error_at("line1")));
    try!(function_returning_code().map_err(error_at("line2")));
    Ok(())
}
fn main() {
    function_with_error().unwrap();
}

目前报错:

<anon>:11:12: 11:17 error: associated type bindings are not allowed here [E0229]
<anon>:11 impl FnOnce(u32) for MyErrorPartial {
                     ^~~~~

【问题讨论】:

    标签: rust higher-order-functions


    【解决方案1】:

    在结构上手动实现Fn* trait 的语法是这样的:

    impl FnOnce<(Arg1,Arg2,Arg3,)> for MyStruct {
        type Output = MyOutput;
        extern "rust-call" fn call_once(args: (Arg1, Arg2, Arg3,)) -> MyOutput {
           // implementation here
        }
    }
    

    请注意,所有参数都以单个元组的形式给出。

    此外,此语法不稳定,需要#![feature(core, unboxed_closures)],因此您不能在 beta 频道上使用它,只能在夜间使用。

    在你的情况下,它会这样翻译:

    impl FnOnce<(u32,)> for MyErrorPartial {
        type Output = MyError;
    
        extern "rust-call" fn call_once(self, args: (u32,)) -> MyError {
            MyError {
                code: args.0,
                location: self.location,
            }
        }
    }
    

    【讨论】:

    • 在 stable 中实现Fn* 是不可能的吗?
    • @Kapichu 看起来是这样:call_once 方法的文档链接到问题#29625,它仍然是开放的。
    猜你喜欢
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2022-09-24
    • 2023-01-14
    • 1970-01-01
    • 2021-03-10
    相关资源
    最近更新 更多