Tha*_*tos 7 generics macros type-inference rust
试图编译以下内容,
fn do_it() -> Result<i32, u32> {
Result::<i32, u32>::Ok(3)
}
fn main() {
println!("{}", do_it());
}
Run Code Online (Sandbox Code Playgroud)
结果是:
./result_test.rs:2:14: 2:17 error: type parameters are not allowed on this type [E0109]
./result_test.rs:2 Result::<i32, u32>::Ok(3)
^~~
Run Code Online (Sandbox Code Playgroud)
为什么这种类型的类型参数不允许?
这是一个最小的例子,我的真实世界的例子是一个宏试图返回以下内容:
match $reader.$read_func() {
Ok(n) => Result::<$read_type, LocalReadError>::Ok(n),
Err(err) => Result::<$read_type, LocalReadError>::Err(
LocalReadError::from(err)
),
}
Run Code Online (Sandbox Code Playgroud)
$read_func是一个函数,$read_type是该函数的返回类型.(如果我有一个程序化的方法来实现这一点,我会这样做;我不知道如何,所以这是一个arg ......); 原样,我得到了上述错误.如果我删除泛型参数的规范,键入干扰会抱怨它无法弄清楚类型.(因为它结束了Result<_, LocalReadError>在的一个分支match,而Result<$read_type, _>?在其他的我真的不知道它说:
error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
match $reader.$read_func() {
^~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
)
注意:下面回答了关于为什么不允许输入类型参数的问题.事实证明,这不是"无法推断出足够类型信息"的原因.(read_func是一个函数,在我的例子中,我正在传递模板化函数,但忘记了模板arg,这是无法推断的.)
这实际上与讨论的枚举不一致,但不足以阻止1.0.
指定类型的工作语法是Result::Ok::<i32, u32>(3).
枚举类似于某种类型(可能与您尝试编写的语法一致)和命名空间(以及命名空间不接受类型参数)之间的某种东西.
要演示枚举是如何命名空间,您可以编写:
use std::result::Result::*;
fn main() {
println!("{:?}", Ok::<i32, u32>(3));
}
Run Code Online (Sandbox Code Playgroud)
这个命名空间方面是枚举的理想属性,但是移动类型参数会直观地认为它们应该是这样的代码会使这种类型的代码非常难以编写.