尝试编译以下内容,
fn do_it() -> Result<i32, u32> {
Result::<i32, u32>::Ok(3)
}
fn main() {
println!("{}", do_it());
}
结果:
./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)
^~~
为什么此类型不允许使用类型参数?
这是一个最小的例子,我的真实世界的例子是一个试图返回以下内容的宏:
match $reader.$read_func() {
Ok(n) => Result::<$read_type, LocalReadError>::Ok(n),
Err(err) => Result::<$read_type, LocalReadError>::Err(
LocalReadError::from(err)
),
}
$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() {
^~~~~~~~~~~~
)
注意:下面回答了关于为什么不允许输入类型参数的问题。事实证明,这不是&#34;无法推断出足够类型信息的原因&#34;。 (read_func
是一个函数,在我的例子中,我传递了模板化函数,但忘记了模板arg,这是无法推断的。)
答案 0 :(得分:9)
这实际上与was discussed的枚举不一致,但认为不足以阻止1.0。
指定类型的工作语法是Result::Ok::<i32, u32>(3)
。
枚举的作用类似于某种类型(可能与您尝试编写的语法一致)和命名空间(以及名称空间不接受类型参数)。
为了演示枚举是如何命名空间的,你可以写:
use std::result::Result::*;
fn main() {
println!("{:?}", Ok::<i32, u32>(3));
}
这个命名空间方面是枚举的理想属性,但是移动类型参数会直观地认为它们应该是这样的代码会使这种类型的代码非常难以编写。