使用Rust的通用FromStr对象可以做些什么?

时间:2015-09-21 04:31:00

标签: rust

Rust的str类有一个parse方法,它返回一个FromStr对象。 parse是模板化的,因此可以手动指定从str解析的类型,例如"3".parse::<i32>()求值为(Result对象包含)32位int 3

但是未指定类型本身似乎不是错误。相反,我在尝试打印生成的(通用/未指定的)FromStr对象时遇到错误:

let foo = "3".parse();
match foo
{
    Ok(m) => println!("foo: {}", m),
    Err(e) => println!("error! {}", e)
}

会在第一行产生错误;相反,我收到以下错误:

<anon>:24:12: 24:13 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
<anon>:24         Ok(m) => println!("foo: {}", m),

(此处,第24行是Ok(m)的行。)

那么这里的m是什么?或者实际上是“无法推断出足够的类型信息”错误,因为parse实际上无法在没有类型说明符的情况下调用,并且编译器只是没有捕获错误直到实际使用结果Ok类型的第一行?

2 个答案:

答案 0 :(得分:7)

  

Rust的str类有parse方法返回FromStr个对象。

停在这里,这是你的错误。

parse不会返回FromStr个对象; FromStr是一个trait,如果你来自OO背景,它可以被认为是一个抽象类,你不能返回一个抽象类型的对象:它是抽象的!

parse确实返回的是某个类型T的实例,它必须实现FromStr接口。

  

但是未指定类型本身似乎不是错误。相反,我在尝试打印生成的(通用/未指定的)FromStr对象

时遇到错误

因为不能有这样的通用/非特定FromStr对象。必须推断(从上下文)或明确拼写出具体类型,此类型必须实现FromStr

  

那么这里的m是什么?

只有你知道它应该是什么,编译器没有,因此抱怨它不知道该怎么做:)

  

或者是“无法推断出足够的类型信息”错误实际上是由于事实上没有类型说明符就不能调用解析,并且编译器只是在第一行之前没有捕获错误实际使用了Ok类型的结果?

基本上

除了在使用结果Ok的第一行之前编译器没有捕获错误,并且编译器在推断类型时立即考虑完整函数的情况并不多。从编译器的角度来看,推断类型的实际线索是立即出现还是50行下降并不重要,它只需要存在于当前函数体中。

从开发者的角度来看,这可能导致关于缺乏类型的抱怨起源于奇怪的地方;这是类型推断的垮台之一。另一方面,编译器无法知道您希望将注释放在何处。毕竟有很多可能性:

// Example 1: immediately specifying the type
fn main() {
    let foo = "3".parse::<i32>();
    match foo
    {
        Ok(m) => println!("foo: {}", m),
        Err(e) => println!("error! {}", e)
    }
}

// Example 2: partially specifying the result type
// Note: the "_" is deduced to be std::num::ParseIntError because
//       this is how `FromStr::Err` is defined for `i32`.
fn main() {
    let foo: Result<i32, _> = "3".parse();
    match foo
    {
        Ok(m) => println!("foo: {}", m),
        Err(e) => println!("error! {}", e)
    }
}

// Example 3: specifying the result type of unwrapping
fn doit() -> Result<(), std::num::ParseIntError> {
    let foo: i32 = try!("3".parse());
    println!("foo: {}", foo);
    Ok(())
}

fn main() {
    match doit()
    {
        Ok(_) => (),
        Err(e) => println!("error! {}", e)
    }
}

// Example 4: letting the type be inferred from a function call
fn callit(f: i32) {
    println!("f: {}", f);
}

fn main() {
    let foo = "3".parse();
    match foo
    {
        Ok(m) => callit(m),
        Err(e) => println!("error! {}", e)
    }
}

答案 1 :(得分:2)

目前还不清楚这里有什么,因为没有足够的信息可以说。它是i32吗?一个u64?包括鲁斯特在内的任何人都不会知道。

你需要做些什么来帮助弄清楚它是什么类型。将其传递给期望特定类型的函数,或者对其进行注释以便可以确定它应该是什么类型。