【问题标题】:Simplify function declaration简化函数声明
【发布时间】:2020-05-24 00:22:27
【问题描述】:

我想简化以下函数的声明:

use regex::Regex;

fn oper<'a, F>(regex: &str, op: F) -> (Regex, Box<dyn Fn(i32, i32) -> i32 + 'a>)
where F: Fn(i32, i32) -> i32 + 'a
{
    (Regex::new(regex).unwrap(), Box::new(op))
}

我尝试将返回值中的Fn trait 替换为F,但它会引发错误:

fn oper<'a, F>(regex: &str, op: F) -> (Regex, Box<dyn F>)
where F: Fn(i32, i32) -> i32 + 'a
{
    (Regex::new(regex).unwrap(), Box::new(op))
}
error[E0404]: expected trait, found type parameter `F`
  --> src/lib.rs:5:55
   |
5  |   fn oper<'a, F>(regex: &str, op: F) -> (Regex, Box<dyn F>)
   |                                                         ^ help: a trait with a similar name exists: `Fn`

error: aborting due to previous error

如何简化此声明以避免重复Fn(i32, i32) -&gt; i32 + 'a

【问题讨论】:

    标签: rust


    【解决方案1】:

    您可以使用this technique。简而言之,定义一个需要Fn(i32, i32) -&gt; i32 的新特征,并为已经实现Fn(i32, i32) -&gt; i32 的任何类型实现它:

    use regex::Regex;
    
    // 1. Create a new trait
    pub trait MyFn: Fn(i32, i32) -> i32 {}
    
    // 2. Implement it
    impl<T> MyFn for T where T: Fn(i32, i32) -> i32 {}
    
    fn oper<'a, F>(regex: &str, op: F) -> (Regex, Box<dyn MyFn + 'a>)
        where F: MyFn + 'a
    {
        (Regex::new(regex).unwrap(), Box::new(op))
    }
    

    但是请注意,这可能比在oper 的签名中重复Fn(i32, i32) -&gt; i32 更易读。

    【讨论】:

    • 谢谢它的工作,即使现在类型推断不那么“聪明”:当使用oper("...", |a, b| a.pow(b as u32))时,它迫使我添加一个闭包参数类型:oper("...", |a: i32, b| a.pow(b as u32))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多