2017-03-17 1 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 FnOnce이 필요한 supertrait FnMut이 구현되어 있지 않습니다. FnOnce관련 유형Output이 선언 된 곳입니다.

  3. 구체적인 구현 유형은 Output이어야합니다.

  4. 특성은 Self을 반환하고 특성은 Self::Output을 반환합니다.

  5. 구현시 call의 두 번째 인수를 허용하지 않습니다. 이 인수는 전달 된 인수가 포함되어 있습니다.

는 또한, 녹의 유형 PascalCase하지 snake_case를 사용, 그래서 Foo을해야합니다.

#![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(); 
} 

는 일반적으로하지만, 단 하나 개의 특성의 구현은 흥미로운 코드를 가지고 것이고 다른 특성의 구현은 위임 것 :

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

관련 문제