我有一个程序,其中在函数中收集用户输入并返回值。在该函数中,它尝试将%lg
输入解析为String
。如果它失败了,而不是恐慌并结束程序,我希望它返回u32
。
是否可以允许任何返回类型?我阅读了Rust Book中的泛型部分,但它没有包含有关返回泛型类型的任何内容。
这是我的代码:
String
答案 0 :(得分:5)
您似乎在这里提出两个不同的问题。
<强> 1。用户如何指定函数的输出类型?
使用通用参数。例如,Iterator::collect
需要一个类型参数B
,用作返回类型。
<强> 2。如何返回两种不同类型的值?
您可以创建一个enum
作为&#34; union&#34;这两种类型:
pub enum Union<A, B> {
ValueA(A),
ValueB(B)
}
在这种情况下,ValueA
或ValueB
案例没有内在含义。
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()
}
请参阅playground和gist