2017-03-17 4 views
2
#![feature(unboxed_closures)] 
#![feature(fn_traits)] 

struct foo; 

impl std::ops::Add for foo { 
    type Output = foo; 
    fn add(self, x: foo) -> foo { 
     println!("Add for foo"); 
     x 
    } 
} 

impl Fn for foo { 
    extern "rust-call" fn call(&self) -> Self { 
     println!("Call for Foo "); 
     self 
    } 
} 

fn main() { 
    let x = foo; 
    let y = foo; 
    x + y; 

    x(); 
} 

私はAddの特性を実装しましたが、構造体を関数として呼び出す方法はわかりません。私はエラーを取得する:structを呼び出し可能にするにはどうすればよいですか?

error[E0243]: wrong number of type arguments: expected 1, found 0 
    --> src/main.rs:14:10 
    | 
14 |  impl Fn for foo { 
    |   ^^ expected 1 type argument 

私は錆に新たなんだ、この事が起こるようにする方法の例を見つけることができません。

答えて

7

は、それを実装する方法を確認するためにを実装している特性を完全に読んでおくと非常に便利です。 Fn traitは次のように定義されています

pub trait Fn<Args>: FnMut<Args> { 
    extern "rust-call" fn call(&self, args: Args) -> Self::Output; 
} 

実装と定義との違いに注意してください?私は多くを参照してください。

  1. 実装はArgsの値を提供していません!これがコンパイラが指しているものです。関連項目Wrong number of type arguments: expected 1 but found 0

  2. 実装では、supertrait が必要なsupertrait FnMutが実装されていません。 FnOnceは、関連タイプOutputが宣言されています。

  3. 実装は、具体的なタイプOutputがどのようにすべきかを定義することを無視しています。

  4. Selfの結果はSelf::Outputを返しますが、実装はSelfを返します。

  5. 実装では、callの2番目の引数を受け入れません。この引数は、渡された引数が含まれています。

それはFooする必要がありますので、また、錆で種類は、PascalCase、ないsnake_caseを使用しています。通常

#![feature(unboxed_closures)] 
#![feature(fn_traits)] 

struct Foo; 

impl Fn<()> for Foo { 
    extern "rust-call" fn call(&self, _args:()) { 
     println!("Call (Fn) for Foo"); 
    } 
} 

impl FnMut<()> for Foo { 
    extern "rust-call" fn call_mut(&mut self, _args:()) { 
     println!("Call (FnMut) for Foo"); 
    } 
} 

impl FnOnce<()> for Foo { 
    type Output =(); 

    extern "rust-call" fn call_once(self, _args:()) { 
     println!("Call (FnOnce) for Foo"); 
    } 
} 

fn main() { 
    let x = Foo; 
    x(); 
} 

しかし、唯一の1つの形質の実装はそれで面白いのコードを持っているでしょうし、他の特性の実装はそれに委譲します:

extern "rust-call" fn call(&self, args:()) { 
    println!("Foo called, took args: {:?}", args); 
} 

// ... 

extern "rust-call" fn call_mut(&mut self, args:()) { 
    self.call(args) 
} 

// ... 

extern "rust-call" fn call_once(self, args:()) { 
    self.call(args) 
} 
+0

おかげでたくさん!非常に良い説明。 –

+0

@АндрейЛедовскихあなたは大歓迎です。役に立つと思われる回答をupvoteし、あなたの問題解決に最も役立った回答を受け入れることを忘れないでください。 – Shepmaster

関連する問題