在将字符串解析为数字时推断类型和使用类型注释

Inferring types and using type annotations when parsing a string to a number

我正在尝试编写一个函数来解析给定字符串中的浮点数。在错误或负值的情况下应该 return 错误。

fn read_value(strvalue: &str) -> Result<f32, Error> {
    match FromStr::from_str(strvalue) {
        None => Err(Error::InvalidValue),
        Some(value) => if value >= 0.0 {Ok(value)} else {Err(Error::InvalidValue)}
    }
}

此代码给出:

src/main.rs:50:27: 50:32 error: the type of this value must be known in this context
src/main.rs:50         Some(value) => if value >= 0.0 {Ok(value)} else {Err(Error::InvalidValue)}

第一点。这个错误对我来说似乎很奇怪,因为如果我理解正确, value 的类型可以自动推断出来。从结果类型来看,value 的类型必须是 f32.

第二个问题。我该如何解决这个错误?或者更一般的——如何在 Rust 中注释表达式类型?

例如在 Haskell 我可以这样写:

if (value :: f32) > 0.0 ...

或者在模式匹配中加入类型注解::

Some(value :: f32) => ...

要解决此问题,我建议使用带有类型参数的 parse 方法。要指定函数类型参数,而不是调用 foo(),您可以调用 foo::<types>():

fn read_value(strvalue: &str) -> Result<f32, u8> {
    match strvalue.parse::<f32>() {
        None => Err(1),
        Some(value) => if value >= 0.0 {Ok(value)} else {Err(2)}
    }
}

另一种没有类型注释的形式(并暗示这可能是一个错误)。这个版本使用了匹配守卫:

fn read_value(strvalue: &str) -> Result<f32, u8> {
    match FromStr::from_str(strvalue) {
        None => Err(1),
        Some(value) if value >= 0.0 => Ok(value),
        _ => Err(2),
    }
}

另一个使用链式方法,将其表示为一系列转换:

fn read_value_chain(strvalue: &str) -> Result<f32, u8> {
    strvalue.parse()
        .ok_or(1)
        .and_then(|v: f32| if v > 0.0 { Ok(v) } else { Err(2) })
}