为什么在 Rust 函数中注释类型时会出现错误 "expected type argument"?
Why do I get the error "expected type argument" when I annotate a type in a Rust function?
我正在研究 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 新手;对不起,如果这是一个菜鸟问题!
Rust 不会 在函数参数位置推断类型。这是设计使然,如 Rust language FAQ 所述:
Why aren't function signatures inferred?
In Rust, declarations tend to come with explicit types, while actual code has its types inferred. There are several reasons for this design:
Mandatory declaration signatures help enforce interface stability at both the module and crate level.
Signatures improve code comprehension for the programmer, eliminating the need for an IDE running an inference algorithm across an entire crate to be able to guess at a function’s argument types; it’s always explicit and nearby.
Mechanically, it simplifies the inference algorithm, as inference only requires looking at one function at a time.
由于 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 to allow you to do different things with message
inside the function. For example, you might want to send message
to another thread, which requires that Builder<A>
implement Send
. Builder
has the following impl (reference):
impl <A> Send for Builder<A> where A: Send + Allocator
表示Builder<A>
可以实现Send
,但前提是A
实现Send
和Allocator
。您可以在 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
那么您将只能在实现 Send
.
的 Builder
上调用 dump_capnp_to_file
我正在研究 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 新手;对不起,如果这是一个菜鸟问题!
Rust 不会 在函数参数位置推断类型。这是设计使然,如 Rust language FAQ 所述:
Why aren't function signatures inferred?
In Rust, declarations tend to come with explicit types, while actual code has its types inferred. There are several reasons for this design:
Mandatory declaration signatures help enforce interface stability at both the module and crate level.
Signatures improve code comprehension for the programmer, eliminating the need for an IDE running an inference algorithm across an entire crate to be able to guess at a function’s argument types; it’s always explicit and nearby.
Mechanically, it simplifies the inference algorithm, as inference only requires looking at one function at a time.
由于 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 to allow you to do different things with message
inside the function. For example, you might want to send message
to another thread, which requires that Builder<A>
implement Send
. Builder
has the following impl (reference):
impl <A> Send for Builder<A> where A: Send + Allocator
表示Builder<A>
可以实现Send
,但前提是A
实现Send
和Allocator
。您可以在 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
那么您将只能在实现 Send
.
Builder
上调用 dump_capnp_to_file