具有特征的通用函数,用于读取抱怨错误特征的数字
Generic function with traits to read a number complaining about Error trait
我正在尝试创建一个通用函数来从标准输入读取数字:
use std::error::Error;
use std::io;
use std::io::Write;
use std::str::FromStr;
fn read_number<F: FromStr>(prompt: &str) -> Result<F, Box<Error>> {
let mut guess = String::new();
let mut sout = io::stdout();
sout.write(prompt.as_bytes())?;
sout.flush()?;
io::stdin().read_line(&mut guess)?;
Ok(guess.trim().parse()?)
}
fn read_until_number<F: FromStr>(prompt: &str) -> F {
loop {
match read_number(prompt) {
Ok(num) => break num,
Err(_) => println!("Please enter valid number."),
};
}
}
fn main() {
let x: u32 = read_until_number("Enter integer:\n");
let y: f32 = read_until_number("Enter float:\n");
println!("You entered this integer: {} and this float: {}", x, y);
}
没用;我收到以下错误:
error[E0277]: the trait bound `<F as std::str::FromStr>::Err: std::error::Error` is not satisfied
--> src/main.rs:16:8
|
16 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `<F as std::str::FromStr>::Err`
|
= help: consider adding a `where <F as std::str::FromStr>::Err: std::error::Error` bound
= note: required because of the requirements on the impl of `std::convert::From<<F as std::str::FromStr>::Err>` for `std::boxed::Box<std::error::Error>`
= note: required by `std::convert::From::from`
错误消息告诉您该怎么做:
consider adding a `where <F as std::str::FromStr>::Err: std::error::Error` bound
遵循建议,但使用更简单的语法:
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error,
这会导致另一个错误,该错误还会告诉您该怎么做:
error[E0310]: the associated type `<F as std::str::FromStr>::Err` may not live long enough
--> src/main.rs:20:8
|
20 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<F as std::str::FromStr>::Err: 'static`...
note: ...so that the type `<F as std::str::FromStr>::Err` will meet its required lifetime bounds
--> src/main.rs:20:8
|
20 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^
遵循建议并将其添加到我们现有的限制中:
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error + 'static,
然后您将得到与 read_until_number
函数相同的错误。重复同样的过程,你最终得到:
use std::error::Error;
use std::io;
use std::io::Write;
use std::str::FromStr;
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error + 'static,
{
let mut guess = String::new();
let mut sout = io::stdout();
sout.write(prompt.as_bytes())?;
sout.flush()?;
io::stdin().read_line(&mut guess)?;
Ok(guess.trim().parse()?)
}
fn read_until_number<F>(prompt: &str) -> F
where
F: FromStr,
F::Err: std::error::Error + 'static,
{
loop {
match read_number(prompt) {
Ok(num) => break num,
Err(_) => println!("Please enter valid number."),
};
}
}
fn main() {
let x: u32 = read_until_number("Enter integer:\n");
let y: f32 = read_until_number("Enter float:\n");
println!("You entered this integer: {} and this float: {}", x, y);
}
为什么需要这个?
implementation of From
for Box<Error>
requires that the type implement std::error::Error
, but the trait FromStr
对关联的 Err
类型没有限制。您必须将限制添加到您的函数才能执行转换。
默认情况下,参数位置中的特征对象具有隐式 'static
绑定,就好像您已经完成 Box<Error + 'static>
一样。您 可以 更改 read_number
以使用更细微的生命周期,但您无法更改 read_until_number
因为错误必须存在于函数之外:
fn read_number<'a, F>(prompt: &'a str) -> Result<F, Box<Error + 'a>>
where
F: FromStr,
F::Err: std::error::Error + 'a,
我正在尝试创建一个通用函数来从标准输入读取数字:
use std::error::Error;
use std::io;
use std::io::Write;
use std::str::FromStr;
fn read_number<F: FromStr>(prompt: &str) -> Result<F, Box<Error>> {
let mut guess = String::new();
let mut sout = io::stdout();
sout.write(prompt.as_bytes())?;
sout.flush()?;
io::stdin().read_line(&mut guess)?;
Ok(guess.trim().parse()?)
}
fn read_until_number<F: FromStr>(prompt: &str) -> F {
loop {
match read_number(prompt) {
Ok(num) => break num,
Err(_) => println!("Please enter valid number."),
};
}
}
fn main() {
let x: u32 = read_until_number("Enter integer:\n");
let y: f32 = read_until_number("Enter float:\n");
println!("You entered this integer: {} and this float: {}", x, y);
}
没用;我收到以下错误:
error[E0277]: the trait bound `<F as std::str::FromStr>::Err: std::error::Error` is not satisfied
--> src/main.rs:16:8
|
16 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `<F as std::str::FromStr>::Err`
|
= help: consider adding a `where <F as std::str::FromStr>::Err: std::error::Error` bound
= note: required because of the requirements on the impl of `std::convert::From<<F as std::str::FromStr>::Err>` for `std::boxed::Box<std::error::Error>`
= note: required by `std::convert::From::from`
错误消息告诉您该怎么做:
consider adding a `where <F as std::str::FromStr>::Err: std::error::Error` bound
遵循建议,但使用更简单的语法:
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error,
这会导致另一个错误,该错误还会告诉您该怎么做:
error[E0310]: the associated type `<F as std::str::FromStr>::Err` may not live long enough
--> src/main.rs:20:8
|
20 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<F as std::str::FromStr>::Err: 'static`...
note: ...so that the type `<F as std::str::FromStr>::Err` will meet its required lifetime bounds
--> src/main.rs:20:8
|
20 | Ok(guess.trim().parse()?)
| ^^^^^^^^^^^^^^^^^^^^^
遵循建议并将其添加到我们现有的限制中:
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error + 'static,
然后您将得到与 read_until_number
函数相同的错误。重复同样的过程,你最终得到:
use std::error::Error;
use std::io;
use std::io::Write;
use std::str::FromStr;
fn read_number<F>(prompt: &str) -> Result<F, Box<Error>>
where
F: FromStr,
F::Err: std::error::Error + 'static,
{
let mut guess = String::new();
let mut sout = io::stdout();
sout.write(prompt.as_bytes())?;
sout.flush()?;
io::stdin().read_line(&mut guess)?;
Ok(guess.trim().parse()?)
}
fn read_until_number<F>(prompt: &str) -> F
where
F: FromStr,
F::Err: std::error::Error + 'static,
{
loop {
match read_number(prompt) {
Ok(num) => break num,
Err(_) => println!("Please enter valid number."),
};
}
}
fn main() {
let x: u32 = read_until_number("Enter integer:\n");
let y: f32 = read_until_number("Enter float:\n");
println!("You entered this integer: {} and this float: {}", x, y);
}
为什么需要这个?
implementation of
From
forBox<Error>
requires that the type implementstd::error::Error
, but the traitFromStr
对关联的Err
类型没有限制。您必须将限制添加到您的函数才能执行转换。默认情况下,参数位置中的特征对象具有隐式
'static
绑定,就好像您已经完成Box<Error + 'static>
一样。您 可以 更改read_number
以使用更细微的生命周期,但您无法更改read_until_number
因为错误必须存在于函数之外:fn read_number<'a, F>(prompt: &'a str) -> Result<F, Box<Error + 'a>> where F: FromStr, F::Err: std::error::Error + 'a,