如何使结构可调用? [英] How do I make a struct callable?

查看:84
本文介绍了如何使结构可调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#![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作为函数调用.我收到错误消息:

I implemented the Add trait, but I don't understand how to call the struct as a function. I get the error:

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的新手,找不到如何实现此功能的示例.

I'm new to Rust, and can't find examples how to make this thing happen.

推荐答案

您还不能在稳定的Rust中实现Fn*特性.只有使用#[feature]

You cannot yet implement the Fn* traits in stable Rust. This is only possible with the nightly compiler using #[feature]!

充分阅读要实现的特征以了解如何实现它非常有用. Fn特征定义为:

It's very useful to fully read the trait that you are implementing to see how to implement it. The Fn trait is defined as:

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

注意到实现和定义之间有什么区别吗?我看到很多:

Notice any differences between the implementation and the definition? I see many:

  1. 该实现未提供Args的值!这就是编译器所指向的.另请参见类型参数数量错误:应为1,但发现为0

  1. The implementation doesn't provide a value for Args! That's what the compiler is pointing at. See also Wrong number of type arguments: expected 1 but found 0

该实现未实现上级特征 FnMut ,它本身需要上级特征 FnOnce . FnOnce是声明关联类型 Output的位置.

The implementation doesn't implement the supertrait FnMut, which itself requires the supertrait FnOnce. FnOnce is where the associated type Output is declared.

该实现忽略了定义Output应该是什么具体类型.

The implementation neglects to define what concrete type Output should be.

实现返回Self,而特征返回Self::Output.

The implementation returns Self while the trait returns Self::Output.

该实现不接受call的第二个参数.此参数包含传入的所有参数.

The implementation doesn't accept the second argument to call. This argument contains any arguments passed in.

此外,Rust中的类型使用PascalCase,而不是snake_case,因此应为Foo.

Additionally, types in Rust use PascalCase, not snake_case, so it should be 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();
}

尽管通常,只有一个特征的实现中会包含有趣的代码,而其他特征的实现会委托给它:

Normally though, only one trait's implementation would have interesting code in it and the other trait implementations would delegate to it:

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)
}

另请参阅:

这篇关于如何使结构可调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆