如何使结构可调用?

问题描述 投票:8回答:1
#![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特性,但我不明白如何将结构称为函数。我收到错误:

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

我是Rust的新手,无法找到如何让这件事发生的例子。

rust implementation traits
1个回答
14
投票

你还不能在稳定的Rust中实现Fn*特性。这只适用于使用#[feature]的夜间编译器!

完全阅读您正在实施的特征以了解如何实现它非常有用。 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 FnMut,它本身需要supertrait FnOnceFnOnce是宣布相关类型Output的地方。
  3. 实现忽略了定义Output应该是什么具体类型。
  4. 当特征返回Self时,实现返回Self::Output
  5. 该实现不接受call的第二个参数。该参数包含传入的任何参数。

另外,Rust中的类型使用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)
}

也可以看看:

© www.soinside.com 2019 - 2024. All rights reserved.