use*_*932 5 syntax traits rust type-alias
我想合作FnMut(&[f32]) -> f32,不要复制/粘贴完整的签名,我想介绍一些别名,但是
type Boo = FnMut(&[f32]) -> f32;
fn f<F: Boo>(mut f: F) {}
Run Code Online (Sandbox Code Playgroud)
导致编译器错误:
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
Run Code Online (Sandbox Code Playgroud)
然后我尝试了:
trait Boo: FnMut(&[f32]) -> f32 {}
fn f<F: Boo>(mut f: F) {}
Run Code Online (Sandbox Code Playgroud)
它编译,但如果我尝试Boo在另一个地方使用特征代替:
trait Boo: FnMut(&[f32]) -> f32 {}
struct X(Vec<Box<Boo>>);
Run Code Online (Sandbox Code Playgroud)
我明白了:
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
Run Code Online (Sandbox Code Playgroud)
有没有办法创建一个FnMut我可以使用的特定别名而不是FnMut(&[f32]) -> f32?
特质别名目前不是该语言的一部分.但是,确切地说有一个公认的RFC.很难准确预测何时实施,但接受RFC代表了在未来的某个时刻实施它的承诺.
您的错误的原因是您的Boo特征是一个子类型,FnMut任何实现也必须提供所需的关联类型Output.但编译器仍然不知道将提供哪种实现,因此您需要告诉它将是什么类型Output:
struct X(Vec<Box<Boo<Output = f32>>>);
Run Code Online (Sandbox Code Playgroud)
这有点笨重,我觉得这是一个需要改进的地方.直觉上,似乎Output可以从中推断-> f32,但我在这里可能是错的.
即使修复了这个错误,Boo严格来说也是一个子类型,FnMut(&[f32])所以你不能只提供任何Boo预期的闭包.关闭也必须实现你的特质.您可以将此作为所有人的一揽子实施FnMut(&[f32]) -> f32,如下所示:
impl <F> Boo for F where F: FnMut(&[f32]) -> f32 {}
Run Code Online (Sandbox Code Playgroud)
现在任何Boo都是FnMut(&[f32]) -> f32(通过子类型),任何FnMut(&[f32]) -> f32都是Boo(通过毯子实现).