2015-10-20 80 views
2

我想要實現的一些具體功能的自定義特徵,即實施性狀FN型

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()); 

所以問題是:有沒有辦法讓我的第一個版本sion of code

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

compile?每次我想要使用我的特質時指定函數的類型真的很煩人。

回答

2

問題是每個函數都有它自己的類型,但可能與另一個函數具有相同的簽名。您對簽名爲fn(i32) -> String的所有功能實施了特徵ToTarget

舉例:您的函數b的類型爲fn(i32) -> collections::string::String {b}(請注意類型中的{b}),但不能明確指定此類型。

你可以做的是落實ToTarget爲實現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() 
} 

但你無法實現ToTargetFn() -> String或任何其他類型的對於這個問題,因爲有可能是一個類型實現Fn(i32) -> StringFn() -> String,這將產生相同類型的兩種不同的實現。據我所知,即使impl specialization在這裏也沒有幫助,所以你運氣不好。

+1

我不確定這會產生什麼樣的效果,但是確保具有相同簽名的所有功能都可以強制進入該簽名是一件容易的事情。 –

+0

感謝您的回答。我的第一個嘗試是爲'Fn'特性實現'ToTarget',但是一旦我寫了第二個實現,我發現我不能第二次實現ToTarget特性。我想我會在這種特殊情況下切換到宏。 –