我想使用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(&[f32]) -> f32

最佳答案

特性别名当前不属于该语言的一部分。但是,确实有一个accepted RFC。很难确切预测何时实现,但是接受RFC表示了在将来某个时候实现该协议(protocol)的 promise 。

发生错误的原因是,您的Boo特性是FnMut的子类型,任何实现都必须提供所需的关联类型Output。但是编译器仍然不知道将提供哪种实现,因此您需要告诉它Output的类型是什么:

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

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

即使已修复该错误,但Boo严格来说是FnMut(&[f32])的子类型,因此您不能仅在需要Boo的情况下提供任何闭包。该关闭还必须实现您的特质。您可以将其作为所有FnMut(&[f32]) -> f32的整体实现,如下所示:
impl <F> Boo for F where F: FnMut(&[f32]) -> f32 {}

现在,任何BooFnMut(&[f32]) -> f32(通过子类型化),并且任何FnMut(&[f32]) -> f32Boo(通过整体实现)。

关于syntax - 有什么方法可以创建特定FnMut的别名?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44246722/

10-10 22:48