I want to implement custom trait for several concrete functions, ie
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());
}
However, this does not compile giving the next error:
<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
However, If I specify the type of b, code compiles:
println!("{}", (b as fn(i32) -> String).custom_str());
So the question is: is there a way to make my first version of code with
println!("{}", b.custom_str());
compile? Specifying type of function every time I want to use my trait is really annoying.
The problem is that every function has its very own type, but might have the same signature as another function. You implemented the trait ToTarget
for all functions with the signature fn(i32) -> String
.
As an example: your function b
has type fn(i32) -> collections::string::String {b}
(note the {b}
in the type), but you cannot specify this type explicitly.
What you can do is implement ToTarget
for all types that that implement Fn(i32) -> String
:
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()
}
But then you cannot implement ToTarget
for Fn() -> String
or any other types for that matter, since there might be a type that implements Fn(i32) -> String
AND Fn() -> String
, which would yield two different implementations for the same type. As far as I can see, even impl specialization won't help here, so you are out of luck.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.