如何在成功时返回用户指定的类型或在失败时返回String?

时间:2016-05-26 12:26:38

标签: generics rust return-type

我有一个程序,其中在函数中收集用户输入并返回值。在该函数中,它尝试将%lg输入解析为String。如果它失败了,而不是恐慌并结束程序,我希望它返回u32

是否可以允许任何返回类型?我阅读了Rust Book中的泛型部分,但它没有包含有关返回泛型类型的任何内容。

这是我的代码:

String

2 个答案:

答案 0 :(得分:5)

您似乎在这里提出两个不同的问题。

<强> 1。用户如何指定函数的输出类型?

使用通用参数。例如,Iterator::collect需要一个类型参数B,用作返回类型。

<强> 2。如何返回两种不同类型的值?

您可以创建一个enum作为&#34; union&#34;这两种类型:

pub enum Union<A, B> {
    ValueA(A),
    ValueB(B)
}

在这种情况下,ValueAValueB案例没有内在含义。

Result枚举类似于此,但它为每个案例增加了意义,即Ok案例表示成功,Err表示错误。

那就是说,我建议您使用Result并且错误情况会返回带有parse错误的读取输入:

use std::io;
use std::str::FromStr;

// 1: T is a type parameter that is used as (part of) return type
//
// 2: Result allows you to return either the parsed T value or
//    the read input value with the parse error 
fn read_input<T: FromStr>(question: &str) -> Result<T, (String, T::Err)> {
    let mut input = String::new();
    println!("{}", question);
    io::stdin()
        .read_line(&mut input)
        .ok()
        .expect("failed to read input");
    match input.trim().parse() {
        Ok(p) => Ok(p),
        Err(err) => Err((input, err))
    }
}

这将允许您向用户写一个很好的错误消息:

fn main() {
    // you can use any type that implements FromStr instead of u32
    match read_input::<u32>("2 + 2?") {
        Ok(ans) => println!("answer: {}", ans),
        Err((input, err)) => println!("\"{}\" is an invalid answer: {}", input, err)
    }
}

答案 1 :(得分:0)

在我看来,为这个特定函数做的事情是从Result行返回input.trim().parse()。如您所说,该方法也可以是通用的,以便从parse-able see docs

的任何内容返回结果
fn read_input<F>(question: &str) -> Result<F, F::Err>
    where F : FromStr 
    {
    let mut input = String::new();
    println!("{}", question);
    io::stdin()
        .read_line(&mut input)
        .expect("failed to read input");
    input.trim().parse()
}

请参阅playgroundgist