【问题标题】:Is there any way to create an alias of a specific FnMut?有没有办法创建特定 FnMut 的别名?
【发布时间】:2017-10-30 00:18:10
【问题描述】:

我想和FnMut(&[f32]) -> f32一起工作, 为了不复制/粘贴完整签名,我想介绍某种别名,但是

type Boo = FnMut(&[f32]) -> f32;

fn f<F: Boo>(mut f: F) {}

导致编译器错误:

error[E0404]: expected trait, found type alias `Boo`
 --> src/main.rs:3:13
  |
3 |     fn f<F: Boo>(mut f: F) {}
  |             ^^^ type aliases cannot be used for traits

然后我尝试了:

trait Boo: FnMut(&[f32]) -> f32 {}

fn f<F: Boo>(mut f: F) {}

它已编译,但如果我尝试在另一个地方使用 Boo 代替 trait:

trait Boo: FnMut(&[f32]) -> f32 {}

struct X(Vec<Box<Boo>>);

我明白了:

error[E0191]: the value of the associated type `Output` (from the trait `std::ops::FnOnce`) must be specified
 --> src/main.rs:3:18
  |
3 | struct X(Vec<Box<Boo>>);
  |                  ^^^ missing associated type `Output` value

有什么方法可以创建我可以使用的特定FnMut 的别名 而不是FnMut(&amp;[f32]) -&gt; f32?

【问题讨论】:

    标签: syntax rust traits type-alias


    【解决方案1】:

    特征别名目前不是该语言的一部分。但是,有一个 accepted RFC 正是为此。很难准确预测何时实施,但接受 RFC 表示承诺在未来某个时间实施。

    您的错误的原因是您的Boo 特征是FnMut 的子类型,并且任何实现还必须提供所需的关联类型Output。但是编译器仍然不知道会提供哪个实现,所以你需要告诉它Output的类型是什么:

    struct X(Vec<Box<Boo<Output = f32>>>);
    

    这有点笨拙,我觉得这是一个需要改进的地方。直觉上,Output 似乎可以从-&gt; f32 推断出来,但我这里可能是错的。

    即使修复了该错误,Boo 严格来说是FnMut(&amp;[f32]) 的子类型,因此您不能只提供预期Boo 的任何闭包。该闭包还必须实现您的特征。您可以将其作为所有FnMut(&amp;[f32]) -&gt; f32 的一揽子实现,如下所示:

    impl <F> Boo for F where F: FnMut(&[f32]) -> f32 {}
    

    现在任何Boo 都是FnMut(&amp;[f32]) -&gt; f32(通过子类型化),任何FnMut(&amp;[f32]) -&gt; f32 都是Boo(通过一揽子实现)。

    【讨论】:

    • 是的,我在提问之前阅读了有关此 RFC 的信息,问题是现在要做什么,使用当前的稳定/测试版编译器。黑客/技巧/宏指令
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多