gpt4 book ai didi

generics - 具有特征的通用函数,用于读取提示错误特征的数字

转载 作者:行者123 更新时间:2023-11-29 08:25:08 24 4
gpt4 key购买 nike

我正在尝试创建一个通用函数来从标准输入读取数字:

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);
}

为什么需要这个?

  1. implementation of From for Box<Error> 要求类型实现 std::error::Error ,但特征 FromStr 对关联的 Err 没有限制类型。您必须向您的函数添加限制才能执行转换。

  2. 默认情况下,参数位置中的特征对象具有隐式 'static绑定(bind),就像你做了一样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,

关于generics - 具有特征的通用函数,用于读取提示错误特征的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49336549/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com