我希望能够使用.into()
在无法进行类型推断的上下文中转换值。这通常是在我想将临时值转换为其他类型以将其传递给泛型函数时。请参阅以下代码以获取示例(playground):
use std::convert::*;
struct NewType(pub i32);
impl From<NewType> for i32 {
fn from(src: NewType) -> i32 {
src.0
}
}
fn main() {
let a = NewType(5);
println!("{}", a.into()); // Understandably won't compile
}
我收到错误:
error[E0282]: type annotations needed
--> src/main.rs:13:20
|
13 | println!("{}", a.into());
| ^^^^^^^^ cannot infer type for `T`
如何正确地告诉编译器我想将a
转换为i32
?
我可以通过明确地向Into
提供类型参数来使其正常工作:Into::<i32>::into(a)
。这比我希望能够实现的更详细和明确,特别是在我没有导入Into
(std::convert::Into::<i32>::into(a)
)的上下文中。 a.into::<i32>()
是可以接受的,但这不是类型参数所在的地方。
a.into() as i32
看起来不错,但这种确切的语法不起作用。
我缺少一个技巧吗?
答案 0 :(得分:9)
您可以使用From::from
:
use std::convert::*;
struct NewType(pub i32);
impl From<NewType> for i32 {
fn from(src: NewType) -> i32 {
src.0
}
}
fn main() {
let a = NewType(5);
println!("{}", i32::from(a));
}
您可以在docs for the convert
module中详细了解相关信息。
答案 1 :(得分:7)
显然,这可以在Rust夜间使用type ascription,这似乎是为此用例设计的功能(playground):
#![feature(type_ascription)]
use std::convert::*;
struct NewType(pub i32);
impl From<NewType> for i32 {
fn from(src: NewType) -> i32 {
src.0
}
}
fn main() {
let a = NewType(5);
println!("{}", a.into(): i32);
}
由于这是在实验性功能中可用的,因此可以合理地得出结论认为它在语言中缺失。
答案 2 :(得分:7)
我认为没有更好的方法。由于type参数位于trait而不是方法into()
,因此turbofish运算符into::<i32>()
不起作用。正如您所说,您可以使用完全限定语法来使其工作:
Into::<i32>::into(a)
请注意,Into
会重新导出std::prelude
,这意味着您永远不必指定完整路径,因为特征始终在范围内。
当然,也总是可以将临时绑定到名称并使用let
的类型注释 - 绑定:
let tmp: i32 = a.into();
但是,将来可能会更好!有Type Ascription for Expressions RFC,已经被接受并实施。该功能仍然不稳定,但如果实现它你可以编写如下内容:
println!("{}", (a.into(): i32)); // still unstable :/
答案 3 :(得分:1)
您可以通过将结果分配给变量来简单地注释结果的类型。
let b: i32 = a.into();
println!("{}", b);