当我在Rust函数中注释类型时,为什么会出现错误“expected type argument”?

时间:2017-05-01 17:29:32

标签: types rust capnproto

我正在玩Rust的capnproto library。因为Rust可以在某些情况下推断类型,我可以这样做:

let mut message = ::capnp::message::Builder::new_default();

无需知道消息的类型。如果我想将message的引用传递给函数,我现在需要知道是什么消息让函数知道会发生什么。

一般来说有没有方便的方法呢?

到目前为止,我已完成以下工作:

let testing: () = message;

因编译错误而失败:

error[E0308]: mismatched types
   --> src/main.rs:197:18
    |
197 |                 let temp: () = message;
    |                           ^^^^^^^ expected (), found struct `capnp::message::Builder`

但是当我输入注释我的函数时如下:

fn example_fn(message: capnp::message::Builder) {...}

我收到如下错误:

error[E0243]: wrong number of type arguments: expected 1, found 0
  --> src/main.rs:72:32
   |
72 | fn dump_capnp_to_file(message: capnp::message::Builder, filename: &str) {
   |                                ^^^^^^^^^^^^^^^^^^^^^^^ expected 1 type argument

错误:由于先前的错误导致中止

我是一个来自C ++背景的Rust的新手;抱歉,如果这是一个菜鸟问题!

1 个答案:

答案 0 :(得分:2)

Rust 不会推断函数参数位置的类型。这是设计的,因为Rust language FAQ状态:

  

为什么没有推断出功能签名?

     

在Rust中,声明往往带有显式类型,而实际代码则推断出它的类型。这种设计有几个原因:

     
      
  • 强制声明签名有助于在模块和包装箱级别强制实施界面稳定性。

  •   
  • 签名可以提高程序员的代码理解能力,无需在整个包中运行推理算法,以便能够猜测函数的参数类型;它总是明确的并且在附近。

  •   
  • 从机制上讲,它简化了推理算法,因为推理只需要一次查看一个函数。

  •   

由于capnp::message::Builder<A>采用类型参数A,您需要通过为A提供值来限定参数类型:

fn dump_capnp_to_file(message: capnp::message::Builder<SomeType>, filename: String) {
//                                                    ^^^^^^^^^^

或者让你的函数也是通用的,所以它可以接受任何类型的A

fn dump_capnp_to_file<A>(message: capnp::message::Builder<A>, filename: String) {
//                   ^^^                                 ^^^

A

上设置界限

如果你采用最后一个选项,你可能需要额外的trait bounds来允许你在函数内部使用message做不同的事情。例如,您可能希望将message发送到另一个线程,这需要Builder<A>实现SendBuilder具有以下impl(reference):

impl <A> Send for Builder<A> where A: Send + Allocator

这意味着Builder<A>可以实现Send,但仅当A实施SendAllocator时才会实现A。您可以在fn dump_capnp_to_file<A>(message: capnp::message::Builder<A>, filename: String) where A: Send + Allocator { // multi-threaded code... } 上创建自己的约束(要求):

Builder<A>

或者(可能稍微更好),直接绑定Send fn dump_capnp_to_file<A>(message: capnp::message::Builder<A>, filename: String) where capnp::message::Builder<A>: Send

dump_capnp_to_file

然后,您只能在实施Builder的{​​{1}}上致电Send