在无法进行类型推断时使用.into()

时间:2016-12-18 11:27:55

标签: rust type-conversion

我希望能够使用.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)。这比我希望能够实现的更详细和明确,特别是在我没有导入Intostd::convert::Into::<i32>::into(a))的上下文中。 a.into::<i32>()是可以接受的,但这不是类型参数所在的地方。

a.into() as i32看起来不错,但这种确切的语法不起作用。

我缺少一个技巧吗?

4 个答案:

答案 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);