为 fn 类型实现特征

Implementing traits for fn type

我想为几个具体函数实现自定义特征,即

trait ToTarget {
    fn custom_str(&self) -> String;
}

impl ToTarget for fn() -> String {
    fn custom_str(&self) -> String {
        self()
    }
}

impl ToTarget for fn(i32) -> String {
    fn custom_str(&self) -> String {
        self(4)
    }
}

fn a() -> String {
    "abc".to_string()
}

fn b(x: i32) -> String {
    x.to_string()
}

fn main() {
    println!("{}", b.custom_str());
}

但是,这不会编译并给出下一个错误:

<anon>:26:22: 26:34 error: no method named `custom_str` found for type `fn(i32) -> collections::string::String {b}` in the current scope
<anon>:26     println!("{}", b.custom_str());
                               ^~~~~~~~~~~~
note: in expansion of format_args!
<std macros>:2:25: 2:56 note: expansion site
<std macros>:1:1: 2:62 note: in expansion of print!
<std macros>:3:1: 3:54 note: expansion site
<std macros>:1:1: 3:58 note: in expansion of println!
<anon>:26:5: 26:36 note: expansion site
<anon>:26:22: 26:34 help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `custom_str`, perhaps you need to implement it:
<anon>:26:22: 26:34 help: candidate #1: `ToTarget`
error: aborting due to previous error
playpen: application terminated with error code 101

但是,如果我指定 b 的类型,代码编译:

println!("{}", (b as fn(i32) -> String).custom_str());

所以问题是:有没有办法用

制作我的第一个代码版本
println!("{}", b.custom_str());

编译?每次我想使用我的特征时都指定函数类型真的很烦人。

问题是每个函数都有自己的类型,但可能与另一个函数具有相同的签名。您为具有签名 fn(i32) -> String.

的所有函数实现了特征 ToTarget

举个例子:你的函数b有类型fn(i32) -> collections::string::String {b}(注意类型中的{b}),但是你不能明确指定这个类型。

你可以做的是为所有实现 Fn(i32) -> String:

的类型实现 ToTarget
trait ToTarget {
    fn custom_str(&self) -> String;
}

impl<T> ToTarget for T where T: Fn(i32) -> String {
    fn custom_str(&self) -> String {
        self(4)
    }
}

fn b(x: i32) -> String {
    x.to_string()
}

但是你不能为 Fn() -> String 或任何其他类型实现 ToTarget,因为可能有一个类型实现了 Fn(i32) -> String AND Fn() -> String,它将为同一类型产生两种不同的实现。据我所知,即使 impl specialization 在这里也无济于事,所以你运气不好。