重庆网站网页设计培训机构,张掖市建设规划局网站,网站未来发展规划,小程序怎么制作网站51.使用?当作错误处理符
? 是 Rust 中的错误处理操作符。通常用于尝试解析或执行可能失败的操作#xff0c;并在出现错误时提前返回错误#xff0c;以避免程序崩溃或出现未处理的错误。
具体来说#xff0c;? 用于处理 Result 或 Option 类型的返回值。
// errors2.rs…51.使用?当作错误处理符
? 是 Rust 中的错误处理操作符。通常用于尝试解析或执行可能失败的操作并在出现错误时提前返回错误以避免程序崩溃或出现未处理的错误。
具体来说? 用于处理 Result 或 Option 类型的返回值。
// errors2.rs
// Say were 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 number of 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 isnt handling the error case at all (and isnt
// 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 DONEuse std::num::ParseIntError;pub fn total_cost(item_quantity: str) - Resulti32, 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);}
}52.在main函数中需要对ParseIntError进行Err匹配
这题只能这么理解,具体原理没翻到
// errors3.rs
// This is a program that is trying to use a completed version of the
// total_cost function from the previous exercise. Its not working though!
// Why not? What should we do to fix it?
// Execute rustlings hint errors3 or use the hint watch subcommand for a hint.// I AM NOT DONEuse std::num::ParseIntError;fn main() {let mut tokens 100;let pretend_user_input 8;// let cost total_cost(pretend_user_input)?;// if cost tokens {// println!(You cant afford that many!);// } else {// tokens - cost;// println!(You now have {} tokens., tokens);// }match total_cost(pretend_user_input) {Ok(cost) {if cost tokens {println!(You cant afford that many!);} else {tokens - cost;println!(You now have {} tokens., tokens);}}Err(message) {}}
}pub fn total_cost(item_quantity: str) - Resulti32, ParseIntError {let processing_fee 1;let cost_per_item 5;let qty item_quantity.parse::i32()?;Ok(qty * cost_per_item processing_fee)
}53.使用if处理不合理的数值范围
// errors4.rs
// Execute rustlings hint errors4 or use the hint watch subcommand for a hint.// I AM NOT DONE#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);#[derive(PartialEq, Debug)]
enum CreationError {Negative,Zero,
}impl PositiveNonzeroInteger {fn new(value: i64) - ResultPositiveNonzeroInteger, CreationError {// Hmm...? Why is this only returning an Ok value?// Ok(PositiveNonzeroInteger(value as u64))if value0 {Ok(PositiveNonzeroInteger(value as u64))}else if value0 {Err(CreationError::Zero)}else{Err(CreationError::Negative)}}
}#[test]
fn test_creation() {assert!(PositiveNonzeroInteger::new(10).is_ok());assert_eq!(Err(CreationError::Negative),PositiveNonzeroInteger::new(-10));assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
}54.在任意实现了error::Error的类型上处理错误类型
// errors5.rs// This program uses an altered version of the code from errors4.// This exercise uses some concepts that we wont get to until later in the course, like Box and the
// From trait. Its not important to understand them in detail right now, but you can read ahead if you like.
// For now, think of the Boxdyn ... type as an I want anything that does ??? type, which, given
// Rusts usual standards for runtime safety, should strike you as somewhat lenient!// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
// type which implements a particular trait. To do so, The Box is declared as of type Boxdyn Trait where Trait is the trait
// the compiler looks for on any value used in that context. For this exercise, that context is the potential errors
// which can be returned in a Result.// What can we use to describe both errors? In other words, is there a trait which both errors implement?// Execute rustlings hint errors5 or use the hint watch subcommand for a hint.// I AM NOT DONEuse std::error;
use std::fmt;
use std::num::ParseIntError;// TODO: update the return type of main() to make this compile.
fn main() - Result(), Boxdyn error::Error {let pretend_user_input 42;let x: i64 pretend_user_input.parse()?;println!(output{:?}, PositiveNonzeroInteger::new(x)?);Ok(())
}// Dont change anything below this line.#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);#[derive(PartialEq, Debug)]
enum CreationError {Negative,Zero,
}impl PositiveNonzeroInteger {fn new(value: i64) - ResultPositiveNonzeroInteger, CreationError {match value {x if x 0 Err(CreationError::Negative),x if x 0 Err(CreationError::Zero),x Ok(PositiveNonzeroInteger(x as u64))}}
}// This is required so that CreationError can implement error::Error.
impl fmt::Display for CreationError {fn fmt(self, f: mut fmt::Formatter) - fmt::Result {let description match *self {CreationError::Negative number is negative,CreationError::Zero number is zero,};f.write_str(description)}
}impl error::Error for CreationError {}55.通过方法映射错误类型?
这题没太看明白,跟着题目提示和GPT提示做下去的
// errors6.rs// Using catch-all error types like Boxdyn error::Error isnt recommended
// for library code, where callers might want to make decisions based on the
// error content, instead of printing it out or propagating it further. Here,
// we define a custom error type to make it possible for callers to decide
// what to do next when our function returns an error.// Execute rustlings hint errors6 or use the hint watch subcommand for a hint.// I AM NOT DONEuse std::num::ParseIntError;// This is a custom error type that we will be using in parse_pos_nonzero().
#[derive(PartialEq, Debug)]
enum ParsePosNonzeroError {Creation(CreationError),ParseInt(ParseIntError)
}impl ParsePosNonzeroError {fn from_creation(err: CreationError) - ParsePosNonzeroError {ParsePosNonzeroError::Creation(err)}// TODO: add another error conversion function here.// fn from_parseint...fn from_parseint(err: ParseIntError) - ParsePosNonzeroError {ParsePosNonzeroError::ParseInt(err)}
}fn parse_pos_nonzero(s: str)- ResultPositiveNonzeroInteger, ParsePosNonzeroError
{// TODO: change this to return an appropriate error instead of panicking// when parse() returns an error.let x: i64 s.parse().map_err(ParsePosNonzeroError::from_parseint)?;;PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
}// Dont change anything below this line.#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);#[derive(PartialEq, Debug)]
enum CreationError {Negative,Zero,
}impl PositiveNonzeroInteger {fn new(value: i64) - ResultPositiveNonzeroInteger, CreationError {match value {x if x 0 Err(CreationError::Negative),x if x 0 Err(CreationError::Zero),x Ok(PositiveNonzeroInteger(x as u64))}}
}#[cfg(test)]
mod test {use super::*;#[test]fn test_parse_error() {// We cant construct a ParseIntError, so we have to pattern match.assert!(matches!(parse_pos_nonzero(not a number),Err(ParsePosNonzeroError::ParseInt(_))));}#[test]fn test_negative() {assert_eq!(parse_pos_nonzero(-555),Err(ParsePosNonzeroError::Creation(CreationError::Negative)));}#[test]fn test_zero() {assert_eq!(parse_pos_nonzero(0),Err(ParsePosNonzeroError::Creation(CreationError::Zero)));}#[test]fn test_positive() {let x PositiveNonzeroInteger::new(42);assert!(x.is_ok());assert_eq!(parse_pos_nonzero(42), Ok(x.unwrap()));}
}56.为某一种类型实现(impl)共享行为(抽象库)
// traits1.rs
// Time to implement some traits!
//
// Your task is to implement the trait
// AppendBar for the type String.
//
// The trait AppendBar has only one function,
// which appends Bar to any object
// implementing this trait.
// Execute rustlings hint traits1 or use the hint watch subcommand for a hint.// I AM NOT DONEtrait AppendBar {fn append_bar(self) - Self;
}impl AppendBar for String {//Add your code herefn append_bar(self) - Self{selfBar}
}fn main() {let s String::from(Foo);let s s.append_bar();println!(s: {}, s);
}#[cfg(test)]
mod tests {use super::*;#[test]fn is_foo_bar() {assert_eq!(String::from(Foo).append_bar(), String::from(FooBar));}#[test]fn is_bar_bar() {assert_eq!(String::from().append_bar().append_bar(),String::from(BarBar));}
}57.自己给Vec写append实现
这道题实际上调用push就可以了
// traits2.rs
//
// Your task is to implement the trait
// AppendBar for a vector of strings.
//
// To implement this trait, consider for
// a moment what it means to append Bar
// to a vector of strings.
//
// No boiler plate code this time,
// you can do this!
// Execute rustlings hint traits2 or use the hint watch subcommand for a hint.// I AM NOT DONEtrait AppendBar {fn append_bar(self) - Self;
}//TODO: Add your code here
impl AppendBar for VecString{fn append_bar(mut self) - Self{self.push(Bar.to_string());self}
}
#[cfg(test)]
mod tests {use super::*;#[test]fn is_vec_pop_eq_bar() {let mut foo vec![String::from(Foo)].append_bar();assert_eq!(foo.pop().unwrap(), String::from(Bar));assert_eq!(foo.pop().unwrap(), String::from(Foo));}
}58.我们不仅可以在impl里面去写具体的实现,也可以在共享行为声明里面完成
// traits3.rs
//
// Your task is to implement the Licensed trait for
// both structures and have them return the same
// information without writing the same function twice.
//
// Consider what you can add to the Licensed trait.
// Execute rustlings hint traits3 or use the hint watch subcommand for a hint.// I AM NOT DONEpub trait Licensed {fn licensing_info(self) - String{String::from(Some information)}
}struct SomeSoftware {version_number: i32,
}struct OtherSoftware {version_number: String,
}impl Licensed for SomeSoftware {} // Dont edit this line
impl Licensed for OtherSoftware {} // Dont edit this line#[cfg(test)]
mod tests {use super::*;#[test]fn is_licensing_info_the_same() {let licensing_info String::from(Some information);let some_software SomeSoftware { version_number: 1 };let other_software OtherSoftware {version_number: v2.0.0.to_string(),};assert_eq!(some_software.licensing_info(), licensing_info);assert_eq!(other_software.licensing_info(), licensing_info);}
}59.创建关于共享行为(trait)的两个实例的泛型
这个真的很妙
// traits4.rs
//
// Your task is to replace the ?? sections so the code compiles.
// Dont change any line other than the marked one.
// Execute rustlings hint traits4 or use the hint watch subcommand for a hint.// I AM NOT DONEpub trait Licensed {fn licensing_info(self) - String {some information.to_string()}
}struct SomeSoftware {}struct OtherSoftware {}impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}// YOU MAY ONLY CHANGE THE NEXT LINE
fn compare_license_typesT:Licensed,U:Licensed(software: T, software_two: U) - bool {software.licensing_info() software_two.licensing_info()
}#[cfg(test)]
mod tests {use super::*;#[test]fn compare_license_information() {let some_software SomeSoftware {};let other_software OtherSoftware {};assert!(compare_license_types(some_software, other_software));}#[test]fn compare_license_information_backwards() {let some_software SomeSoftware {};let other_software OtherSoftware {};assert!(compare_license_types(other_software, some_software));}
}60.使用来放行实现了多种共享行为的类型
// traits5.rs
//
// Your task is to replace the ?? sections so the code compiles.
// Dont change any line other than the marked one.
// Execute rustlings hint traits5 or use the hint watch subcommand for a hint.// I AM NOT DONEpub trait SomeTrait {fn some_function(self) - bool {true}
}pub trait OtherTrait {fn other_function(self) - bool {true}
}struct SomeStruct {}
struct OtherStruct {}impl SomeTrait for SomeStruct {}
impl OtherTrait for SomeStruct {}impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}// YOU MAY ONLY CHANGE THE NEXT LINE
fn some_funcT:SomeTraitOtherTrait(item: T) - bool {item.some_function() item.other_function()
}fn main() {some_func(SomeStruct {});some_func(OtherStruct {});
}