mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 12:39:42 +00:00
add type conversions - From/Into
This commit is contained in:
139
solutions/type-conversions/from-into.md
Normal file
139
solutions/type-conversions/from-into.md
Normal file
@ -0,0 +1,139 @@
|
||||
1.
|
||||
```rust
|
||||
fn main() {
|
||||
// impl From<bool> for i32
|
||||
let i1:i32 = false.into();
|
||||
let i2:i32 = i32::from(false);
|
||||
assert_eq!(i1, i2);
|
||||
assert_eq!(i1, 0);
|
||||
|
||||
let i3: u32 = 'a'.into();
|
||||
|
||||
let s: String = 'a'.into();
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
// impl From<bool> for i32
|
||||
let i1:i32 = false.into();
|
||||
let i2:i32 = i32::from(false);
|
||||
assert_eq!(i1, i2);
|
||||
assert_eq!(i1, 0);
|
||||
|
||||
let i3: u32 = 'a' as u32 ;
|
||||
|
||||
let s: String = String::from('a');
|
||||
}
|
||||
```
|
||||
|
||||
2.
|
||||
```rust
|
||||
// From is now included in `std::prelude`, so there is no need to introduce it into the current scope
|
||||
// use std::convert::From;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Number {
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl From<i32> for Number {
|
||||
// IMPLEMENT `from` method
|
||||
fn from(item: i32) -> Self {
|
||||
Number { value: item }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let num = Number::from(30);
|
||||
assert_eq!(num.value, 30);
|
||||
|
||||
let num: Number = 30.into();
|
||||
assert_eq!(num.value, 30);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
3.
|
||||
```rust
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::num;
|
||||
|
||||
enum CliError {
|
||||
IoError(io::Error),
|
||||
ParseError(num::ParseIntError),
|
||||
}
|
||||
|
||||
impl From<io::Error> for CliError {
|
||||
fn from(error: io::Error) -> Self {
|
||||
CliError::IoError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<num::ParseIntError> for CliError {
|
||||
fn from(error: num::ParseIntError) -> Self {
|
||||
CliError::ParseError(error)
|
||||
}
|
||||
}
|
||||
|
||||
fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
|
||||
// ? automatically converts io::Error to CliError
|
||||
let contents = fs::read_to_string(&file_name)?;
|
||||
// num::ParseIntError -> CliError
|
||||
let num: i32 = contents.trim().parse()?;
|
||||
Ok(num)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
4.
|
||||
```rust
|
||||
fn main() {
|
||||
let n: i16 = 256;
|
||||
|
||||
let n: u8 = match n.try_into() {
|
||||
Ok(n) => n,
|
||||
Err(e) => {
|
||||
println!("there is an error when converting: {:?}, but we catch it", e.to_string());
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
assert_eq!(n, 0);
|
||||
|
||||
println!("Success!")
|
||||
}
|
||||
```
|
||||
|
||||
5.
|
||||
```rust,editable
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct EvenNum(i32);
|
||||
|
||||
impl TryFrom<i32> for EvenNum {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||
if value % 2 == 0 {
|
||||
Ok(EvenNum(value))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(EvenNum::try_from(8), Ok(EvenNum(8)));
|
||||
assert_eq!(EvenNum::try_from(5), Err(()));
|
||||
|
||||
let result: Result<EvenNum, ()> = 8i32.try_into();
|
||||
assert_eq!(result, Ok(EvenNum(8)));
|
||||
let result: Result<EvenNum, ()> = 5i32.try_into();
|
||||
assert_eq!(result, Err(()));
|
||||
}
|
||||
```
|
Reference in New Issue
Block a user