Appearance
Error 2: exercises/error_handling/errors2.rs
题目
rust
// errors2.rs
//
// Say we're writing a game where you can buy items with tokens. All items cost
// 5 tokens, and whenever you purchase items there is a processing fee of 1
// token. A player of the game will type in how many items they want to buy, and
// the `total_cost` function will calculate the total cost of the tokens. Since
// the player typed in the quantity, though, we get it as a string-- and they
// might have typed anything, not just numbers!
//
// Right now, this function isn't handling the error case at all (and isn't
// handling the success case properly either). What we want to do is: if we call
// the `parse` function on a string that is not a number, that function will
// return a `ParseIntError`, and in that case, we want to immediately return
// that error from our function and not try to multiply and add.
//
// There are at least two ways to implement this that are both correct-- but one
// is a lot shorter!
//
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
use std::num::ParseIntError;
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
Ok(qty * cost_per_item + processing_fee)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn item_quantity_is_a_valid_number() {
assert_eq!(total_cost("34"), Ok(171));
}
#[test]
fn item_quantity_is_an_invalid_number() {
assert_eq!(
total_cost("beep boop").unwrap_err().to_string(),
"invalid digit found in string"
);
}
}
假设我们正在编写一个游戏,您可以在其中使用代币购买物品。所有物品均需花费 5 个代币,每当您购买物品时,都会产生 1 个代币的手续费。 游戏玩家将输入他们想要购买的物品数量,total_cost
函数将计算代币的总成本。 不过,由于玩家输入了数量,我们将其作为字符串获取,而且他们可能输入了任何内容,而不仅仅是数字!
现在,这个函数根本不处理错误情况(也没有正确处理成功情况)。 我们想要做的是:如果我们对不是数字的字符串调用parse
函数,该函数将返回ParseIntError
,在这种情况下,我们希望立即从函数中返回该错误而不是尝试乘法和加法。
至少有两种方法可以实现这一点,而且都是正确的,但其中一种要短得多!
题目解析
处理这个问题,一种方法是使用对item_quantity.parse::<i32>()
的结果使用match
语句,用来处理Ok(something)
和Err(something)
。
rust
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
match qty {
Ok(qtyn) => Ok(qtyn * cost_per_item + processing_fee),
Err(err) => Err(err),
}
// Ok(qty * cost_per_item + processing_fee)
}
另一种方式是使用?
运算符,它的作用与您所做的匹配语句的作用几乎相同。
rust
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee)
}