有没有办法创建特定FnMut的别名?

时间:2017-05-29 16:14:06

标签: syntax rust traits type-alias

我想与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 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

1 个答案:

答案 0 :(得分:6)

特质别名目前不是该语言的一部分。但是,确实存在accepted RFC。很难准确预测何时实施,但接受RFC代表了在未来某个时候实施它的承诺。

错误的原因是您的/*** client.js ***/ // asign a change event into input tag 'change input' : function(event,template){ var file = event.target.files[0]; //assuming 1 file only if (!file) return; var reader = new FileReader(); //create a reader according to HTML5 File API reader.onload = function(event){ var buffer = new Uint8Array(reader.result) // convert to binary Meteor.call('saveFile', buffer); } reader.readAsArrayBuffer(file); //read the file as arraybuffer } /*** server.js ***/ Files = new Mongo.Collection('files'); Meteor.methods({ 'saveFile': function(buffer){ Files.insert({data:buffer}) } }); 特征是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 {} 都是Boo(通过子类型),任何FnMut(&[f32]) -> f32都是FnMut(&[f32]) -> f32(通过一揽子实施)。

相关问题