mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 12:39:42 +00:00
Merge branch 'sunface:master' into lifetimes-practice
This commit is contained in:
@ -85,4 +85,17 @@ fn main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
6.
|
||||
```rust
|
||||
fn main() {
|
||||
let mut v = String::from("hello,");
|
||||
let r = &mut v;
|
||||
|
||||
match r {
|
||||
// The type of value is &mut String
|
||||
value => value.push_str(" world!")
|
||||
}
|
||||
}
|
||||
```
|
177
solutions/result-panic/result.md
Normal file
177
solutions/result-panic/result.md
Normal file
@ -0,0 +1,177 @@
|
||||
1.
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
let n1 = n1_str.parse::<i32>();
|
||||
let n2 = n2_str.parse::<i32>();
|
||||
Ok(n1.unwrap() * n2.unwrap())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = multiply("10", "2");
|
||||
assert_eq!(result, Ok(20));
|
||||
|
||||
let result = multiply("4", "2");
|
||||
assert_eq!(result.unwrap(), 8);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
2.
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
// IMPLEMENT multiply with ?
|
||||
// DON'T use unwrap here
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
let n1 = n1_str.parse::<i32>()?;
|
||||
let n2 = n2_str.parse::<i32>()?;
|
||||
Ok(n1 * n2)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(multiply("3", "4").unwrap(), 12);
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
3.
|
||||
```rust
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
|
||||
fn read_file1() -> Result<String, io::Error> {
|
||||
let f = File::open("hello.txt");
|
||||
let mut f = match f {
|
||||
Ok(file) => file,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let mut s = String::new();
|
||||
match f.read_to_string(&mut s) {
|
||||
Ok(_) => Ok(s),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_file2() -> Result<String, io::Error> {
|
||||
let mut s = String::new();
|
||||
|
||||
File::open("hello.txt")?.read_to_string(&mut s)?;
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(read_file1().unwrap_err().to_string(), read_file2().unwrap_err().to_string());
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
4.
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
fn add_two(n_str: &str) -> Result<i32, ParseIntError> {
|
||||
n_str.parse::<i32>().map(|num| num +2)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add_two("4").unwrap(), 6);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
fn add_two(n_str: &str) -> Result<i32, ParseIntError> {
|
||||
n_str.parse::<i32>().and_then(|num| Ok(num +2))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add_two("4").unwrap(), 6);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
5.
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
// With the return type rewritten, we use pattern matching without `unwrap()`.
|
||||
// But it's so Verbose..
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
match n1_str.parse::<i32>() {
|
||||
Ok(n1) => {
|
||||
match n2_str.parse::<i32>() {
|
||||
Ok(n2) => {
|
||||
Ok(n1 * n2)
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
// Rewriting `multiply` to make it succinct
|
||||
// You MUST USING `and_then` and `map` here
|
||||
fn multiply1(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
// IMPLEMENT...
|
||||
n1_str.parse::<i32>().and_then(|n1| {
|
||||
n2_str.parse::<i32>().map(|n2| n1 * n2)
|
||||
})
|
||||
}
|
||||
|
||||
fn print(result: Result<i32, ParseIntError>) {
|
||||
match result {
|
||||
Ok(n) => println!("n is {}", n),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// This still presents a reasonable answer.
|
||||
let twenty = multiply1("10", "2");
|
||||
print(twenty);
|
||||
|
||||
// The following now provides a much more helpful error message.
|
||||
let tt = multiply("t", "2");
|
||||
print(tt);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
6.
|
||||
```rust
|
||||
use std::num::ParseIntError;
|
||||
|
||||
// Define a generic alias for a `Result` with the error type `ParseIntError`.
|
||||
type Res<T> = Result<T, ParseIntError>;
|
||||
|
||||
// Use the above alias to refer to our specific `Result` type.
|
||||
fn multiply(first_number_str: &str, second_number_str: &str) -> Res<i32> {
|
||||
first_number_str.parse::<i32>().and_then(|first_number| {
|
||||
second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
|
||||
})
|
||||
}
|
||||
|
||||
// Here, the alias again allows us to save some space.
|
||||
fn print(result: Res<i32>) {
|
||||
match result {
|
||||
Ok(n) => println!("n is {}", n),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
print(multiply("10", "2"));
|
||||
print(multiply("t", "2"));
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user