如何使用参数定义特征并返回类似Fn的类型?

时间:2017-10-06 23:43:33

标签: syntax rust closures traits

我对以下代码(Listing 13-9)感到困惑:

struct Cacher<T>
where
    T: Fn(i32) -> i32,
{
    calculation: T,
    value: Option<i32>,
}

我理解Fn是一个特征,但通常一个特征没有参数和返回类型。如何定义Fn等特征?

我试图查看at the definition(实际上是FnOnce,但Fn已绑定FnMutFnMut已绑定FnOnce ... ),但我仍然感到困惑。 <Args>是什么意思?然后还something written about it in the Nomicon;但我不明白:

  

Fn(a, b, c) -> d本身只是不稳定真实 Fn特征的糖

1 个答案:

答案 0 :(得分:5)

  

如何定义带有参数的特征并返回类型如Fn?

如果您的意思是语法MyTrait(A) -> B,则不能。特征与#34;参数&#34;和&#34;返回类型&#34;是特殊的,仅限于FnFnMutFnOnce特征。这是硬编码到编译器中的。甚至还有一条特定的错误消息:

error: parenthetical notation is only stable when used with `Fn`-family traits (see issue #29625)
 --> src/main.rs:5:8
  |
5 |     A: MyTrait(A) -> B,
  |        ^^^^^^^^^^^^^^^

话虽如此,这种语法已经成为标准特征语法的一部分。您可以在文档中看到FnOnce的内容:

pub trait FnOnce<Args> {
    type Output;
    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

编译器将Fn(A, B, C) -> Z转换为Fn<(A, B, C), Output = Z>Args是标准特征泛型类型参数,Output是标准关联类型。 "rust-call" ABI是一些内部编译器机制,可以提高效率,大多数时候都可以忽略。

您完全可以使用通用参数和相关类型创建自己的特征。您不能使用括号表示法。