Merge pull request #287 from Tanish-Eagle/edit
Edited type-conversionEdit
This commit is contained in:
commit
bce4f2116f
|
@ -15,7 +15,7 @@ fn main() {
|
||||||
|
|
||||||
assert_eq!(integer, 'b' as u8);
|
assert_eq!(integer, 'b' as u8);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -23,17 +23,17 @@ fn main() {
|
||||||
```rust,editable
|
```rust,editable
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(u8::MAX, 255);
|
assert_eq!(u8::MAX, 255);
|
||||||
// the max of `u8` is 255 as shown above.
|
// The max of `u8` is 255 as shown above.
|
||||||
// so the below code will cause an overflow error: literal out of range for `u8`.
|
// so the below code will cause an overflow error: literal out of range for `u8`.
|
||||||
// PLEASE looking for clues within compile errors to FIX it.
|
// PLEASE looking for clues within compile errors to FIX it.
|
||||||
// DON'T modify any code in main.
|
// DON'T modify any code in main.
|
||||||
let v = 1000 as u8;
|
let v = 1000 as u8;
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
3. ππ when casting any value to an unsigned type `T`, `T::MAX + 1` is added or subtracted until the value fits into the new type.
|
3. ππ When casting any value to an unsigned type `T`, `T::MAX + 1` is added or subtracted until the value fits into the new type.
|
||||||
```rust,editable
|
```rust,editable
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(1000 as u16, __);
|
assert_eq!(1000 as u16, __);
|
||||||
|
@ -67,7 +67,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
4. πππ Raw pointer can be converted to memory address (integer) and vice versa
|
4. πππ Raw pointers can be converted to memory address (integer) and vice versa.
|
||||||
```rust,editable
|
```rust,editable
|
||||||
|
|
||||||
// FILL in the blanks
|
// FILL in the blanks
|
||||||
|
@ -78,13 +78,13 @@ fn main() {
|
||||||
let second_address = first_address + 4; // 4 == std::mem::size_of::<i32>()
|
let second_address = first_address + 4; // 4 == std::mem::size_of::<i32>()
|
||||||
let p2: *mut i32 = second_address __; // p2 points to the 2nd element in values
|
let p2: *mut i32 = second_address __; // p2 points to the 2nd element in values
|
||||||
unsafe {
|
unsafe {
|
||||||
// add one to the second element
|
// Add one to the second element
|
||||||
__
|
__
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(values[1], 3);
|
assert_eq!(values[1], 3);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -100,6 +100,6 @@ fn main() {
|
||||||
assert_eq!(std::mem::size_of_val(&*b), __)
|
assert_eq!(std::mem::size_of_val(&*b), __)
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,7 +8,7 @@ The `Into` trait is simply the reciprocal of the `From` trait. That is, if you h
|
||||||
|
|
||||||
Using the `Into` trait will typically require the type annotations as the compiler is unable to determine this most of the time.
|
Using the `Into` trait will typically require the type annotations as the compiler is unable to determine this most of the time.
|
||||||
|
|
||||||
For example we can easily convert `&str` into `String` :
|
For example, we can easily convert `&str` into `String` :
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
let my_str = "hello";
|
let my_str = "hello";
|
||||||
|
@ -16,12 +16,12 @@ fn main() {
|
||||||
// three conversions below all depends on the fact: String implements From<&str>:
|
// three conversions below all depends on the fact: String implements From<&str>:
|
||||||
let string1 = String::from(my_str);
|
let string1 = String::from(my_str);
|
||||||
let string2 = my_str.to_string();
|
let string2 = my_str.to_string();
|
||||||
// explict type annotation is required here
|
// Explicit type annotation is required here
|
||||||
let string3: String = my_str.into();
|
let string3: String = my_str.into();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
because the standard library has already implemented this for us : `impl From<&'_ str> for String` .
|
Because the standard library has already implemented this for us : `impl From<&'_ str> for String` .
|
||||||
|
|
||||||
Some implementations of `From` trait can be found [here](https://doc.rust-lang.org/stable/std/convert/trait.From.html#implementors).
|
Some implementations of `From` trait can be found [here](https://doc.rust-lang.org/stable/std/convert/trait.From.html#implementors).
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ fn main() {
|
||||||
// FIX the error in two ways
|
// FIX the error in two ways
|
||||||
let s: String = 'a' as String;
|
let s: String = 'a' as String;
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ fn main() {
|
||||||
let num: Number = __;
|
let num: Number = __;
|
||||||
assert_eq!(num.value, 30);
|
assert_eq!(num.value, 30);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ fn main() {
|
||||||
|
|
||||||
assert_eq!(n, __);
|
assert_eq!(n, __);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -166,6 +166,6 @@ fn main() {
|
||||||
let result: Result<EvenNum, ()> = 5i32.try_into();
|
let result: Result<EvenNum, ()> = 5i32.try_into();
|
||||||
assert_eq!(result, __);
|
assert_eq!(result, __);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
|
@ -1,7 +1,7 @@
|
||||||
# Others
|
# Others
|
||||||
|
|
||||||
### Convert any type to String
|
### Convert any type to String
|
||||||
To convert any type to `String`, you can simply the `ToString` trait for that type. Rather than doing that directly, you should implement the `fmt::Display` trait which will automatically provides `ToString` and also allows you to print the type with `println!`.
|
To convert any type to `String`, you can simply use the `ToString` trait for that type. Rather than doing that directly, you should implement the `fmt::Display` trait which will automatically provides `ToString` and also allows you to print the type with `println!`.
|
||||||
|
|
||||||
1. ππ
|
1. ππ
|
||||||
```rust,editable
|
```rust,editable
|
||||||
|
@ -22,14 +22,14 @@ fn main() {
|
||||||
assert_eq!(origin.__, "The point is (0, 0)");
|
assert_eq!(origin.__, "The point is (0, 0)");
|
||||||
assert_eq!(format!(__), "The point is (0, 0)");
|
assert_eq!(format!(__), "The point is (0, 0)");
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parse a String
|
### Parse a String
|
||||||
2. πππ We can use `parse` method to convert a `String` into a `i32` number, this is becuase `FromStr` is implemented for `i32` type in standard library: `impl FromStr for i32`
|
2. πππ We can use `parse` method to convert a `String` into a `i32` number, this is because `FromStr` is implemented for `i32` type in standard library: `impl FromStr for i32`
|
||||||
```rust,editable
|
```rust,editable
|
||||||
// To use `from_str` method, you needs to introduce this trait into the current scope.
|
// To use `from_str` method, you need to introduce this trait into the current scope.
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
fn main() {
|
fn main() {
|
||||||
let parsed: i32 = "5".__.unwrap();
|
let parsed: i32 = "5".__.unwrap();
|
||||||
|
@ -38,7 +38,7 @@ fn main() {
|
||||||
let sum = parsed + turbo_parsed + from_str;
|
let sum = parsed + turbo_parsed + from_str;
|
||||||
assert_eq!(sum, 35);
|
assert_eq!(sum, 35);
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -74,14 +74,14 @@ fn main() {
|
||||||
let p = __;
|
let p = __;
|
||||||
assert_eq!(p.unwrap(), Point{ x: 3, y: 4} );
|
assert_eq!(p.unwrap(), Point{ x: 3, y: 4} );
|
||||||
|
|
||||||
println!("Success!")
|
println!("Success!");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deref
|
### Deref
|
||||||
You can find all the examples and exercises of the `Deref` trait [here](https://practice.rs/smart-pointers/deref.html).
|
You can find all the examples and exercises of the `Deref` trait [here](https://practice.rs/smart-pointers/deref.html).
|
||||||
|
|
||||||
### transmute
|
### Transmute
|
||||||
`std::mem::transmute` is a **unsafe function** can be used to reinterprets the bits of a value of one type as another type. Both of the original and the result types must have the same size and neither of them can be invalid.
|
`std::mem::transmute` is a **unsafe function** can be used to reinterprets the bits of a value of one type as another type. Both of the original and the result types must have the same size and neither of them can be invalid.
|
||||||
|
|
||||||
`transmute` is semantically equivalent to a bitwise move of one type into another. It copies the bits from the source value into the destination value, then forgets the original, seems equivalent to C's `memcpy` under the hood.
|
`transmute` is semantically equivalent to a bitwise move of one type into another. It copies the bits from the source value into the destination value, then forgets the original, seems equivalent to C's `memcpy` under the hood.
|
||||||
|
@ -126,9 +126,9 @@ fn main() {
|
||||||
|
|
||||||
let num = unsafe { std::mem::transmute::<[u8; 4], u32>(raw_bytes) };
|
let num = unsafe { std::mem::transmute::<[u8; 4], u32>(raw_bytes) };
|
||||||
|
|
||||||
// use `u32::from_ne_bytes` instead
|
// Use `u32::from_ne_bytes` instead
|
||||||
let num = u32::from_ne_bytes(raw_bytes);
|
let num = u32::from_ne_bytes(raw_bytes);
|
||||||
// or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
|
// Or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
|
||||||
let num = u32::from_le_bytes(raw_bytes);
|
let num = u32::from_le_bytes(raw_bytes);
|
||||||
assert_eq!(num, 0x12345678);
|
assert_eq!(num, 0x12345678);
|
||||||
let num = u32::from_be_bytes(raw_bytes);
|
let num = u32::from_be_bytes(raw_bytes);
|
||||||
|
@ -150,7 +150,7 @@ fn main() {
|
||||||
let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
|
let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
|
||||||
|
|
||||||
/*Turning an &str into a &[u8]: */
|
/*Turning an &str into a &[u8]: */
|
||||||
// this is not a good way to do this.
|
// This is not a good way to do this.
|
||||||
let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
|
let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
|
||||||
assert_eq!(slice, &[82, 117, 115, 116]);
|
assert_eq!(slice, &[82, 117, 115, 116]);
|
||||||
|
|
||||||
|
|
Loadingβ¦
Reference in New Issue