Merge pull request #272 from Tanish-Eagle/editing

Editing
This commit is contained in:
Sunface 2022-07-20 09:18:37 +08:00 committed by GitHub
commit d91ca79253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 55 deletions

View File

@ -11,7 +11,7 @@ The hash table implementation is a Rust port of Googles [SwissTable](https://
```rust,editable
// FILL in the blanks and FIX the erros
// FILL in the blanks and FIX the errors
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
@ -20,12 +20,12 @@ fn main() {
scores.insert("Ashley", 69.0);
scores.insert("Katie", "58");
// get returns a Option<&V>
// Get returns an Option<&V>
let score = scores.get("Sunface");
assert_eq!(score, Some(98));
if scores.contains_key("Daniel") {
// indexing return a value V
// Indexing returns a value V
let score = scores["Daniel"];
assert_eq!(score, __);
scores.remove("Daniel");
@ -34,7 +34,7 @@ fn main() {
assert_eq!(scores.len(), __);
for (name, score) in scores {
println!("The score of {} is {}", name, score)
println!("The score of {} is {}", name, score);
}
}
```
@ -56,12 +56,12 @@ fn main() {
}
// IMPLEMENT team_map2 in two ways
// tips: one of the approaches is to use `collect` method
// Tips: one of the approaches is to use `collect` method
let teams_map2...
assert_eq!(teams_map1, teams_map2);
println!("Success!")
println!("Success!");
}
```
@ -71,16 +71,16 @@ fn main() {
// FILL in the blanks
use std::collections::HashMap;
fn main() {
// type inference lets us omit an explicit type signature (which
// Type inference lets us omit an explicit type signature (which
// would be `HashMap<&str, u8>` in this example).
let mut player_stats = HashMap::new();
// insert a key only if it doesn't already exist
// Insert a key only if it doesn't already exist
player_stats.entry("health").or_insert(100);
assert_eq!(player_stats["health"], __);
// insert a key using a function that provides a new value only if it
// Insert a key using a function that provides a new value only if it
// doesn't already exist
player_stats.entry("health").or_insert_with(random_stat_buff);
assert_eq!(player_stats["health"], __);
@ -92,11 +92,11 @@ fn main() {
*health -= 50;
assert_eq!(*health, __);
println!("Success!")
println!("Success!");
}
fn random_stat_buff() -> u8 {
// could actually return some random value here - let's just return
// Could actually return some random value here - let's just return
// some fixed value for now
42
}
@ -161,7 +161,7 @@ fn main() {
let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
map.insert(1, 2);
map.insert(3, 4);
// indeed ,the capacity of HashMap is not 100, so we can't compare the equality here.
// Indeed ,the capacity of HashMap is not 100, so we can't compare the equality here.
assert!(map.capacity() >= 100);
// Shrinks the capacity of the map with a lower limit. It will drop
@ -176,7 +176,7 @@ fn main() {
// and possibly leaving some space in accordance with the resize policy.
map.shrink_to_fit();
assert!(map.capacity() >= 2);
println!("Success!")
println!("Success!");
}
```
@ -196,12 +196,12 @@ fn main() {
let v2 = "hello".to_string();
let mut m2 = HashMap::new();
// ownership moved here
// Ownership moved here
m2.insert(v2, v1);
assert_eq!(v2, "hello");
println!("Success!")
println!("Success!");
}
```
@ -212,7 +212,7 @@ The usage of third-party hash looks like this:
```rust
use std::hash::BuildHasherDefault;
use std::collections::HashMap;
// introduce a third party hash function
// Introduce a third party hash function
use twox_hash::XxHash64;

View File

@ -1,5 +1,5 @@
# String
`std::string::String` is a UTF-8 encoded, growable string. It is the most common string type we used in daily dev, it also has ownership over the string contents.
`std::string::String` is a UTF-8 encoded, growable string. It is the most common string type we used in daily development, it also has ownership over the string contents.
### Basic operations
1. 🌟🌟
@ -7,7 +7,7 @@
// FILL in the blanks and FIX errors
// 1. Don't use `to_string()`
// 2. Dont't add/remove any code line
// 2. Don't add/remove any code line
fn main() {
let mut s: String = "hello, ";
s.push_str("world".to_string());
@ -17,7 +17,7 @@ fn main() {
assert_eq!(s, "hello, world!");
println!("Success!")
println!("Success!");
}
fn move_ownership(s: String) {
@ -36,7 +36,7 @@ A `String` is stored as a vector of bytes (`Vec<u8>`), but guaranteed to always
fn main() {
let mut s = String::from("hello, world");
let slice1: &str = __; // in two ways
let slice1: &str = __; // In two ways
assert_eq!(slice1, "hello, world");
let slice2 = __;
@ -46,37 +46,37 @@ fn main() {
slice3.push('!');
assert_eq!(slice3, "hello, world!");
println!("Success!")
println!("Success!");
}
```
3. 🌟🌟
```rust,editable
// Question: how many heap allocations are happened here ?
// Question: how many heap allocations are happening here?
// Your answer:
fn main() {
// Create a String type based on `&str`
// the type of string literals is `&str`
// The type of string literals is `&str`
let s: String = String::from("hello, world!");
// create a slice point to String `s`
// Create a slice point to String `s`
let slice: &str = &s;
// create a String type based on the recently created slice
// Create a String type based on the recently created slice
let s: String = slice.to_string();
assert_eq!(s, "hello, world!");
println!("Success!")
println!("Success!");
}
```
### UTF-8 & Indexing
Strings are always valid UTF-8. This has a few implications:
- the first of which is that if you need a non-UTF-8 string, consider [OsString](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html). It is similar, but without the UTF-8 constraint.
- The second implication is that you cannot index into a String
- The first of which is that if you need a non-UTF-8 string, consider [OsString](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html). It is similar, but without the UTF-8 constraint.
- The second implication is that you cannot index into a String.
Indexing is intended to be a constant-time operation, but UTF-8 encoding does not allow us to do this. Furthermore, its not clear what sort of thing the index should return: a byte, a codepoint, or a grapheme cluster. The bytes and chars methods return iterators over the first two, respectively.
@ -90,22 +90,22 @@ fn main() {
let slice1 = s[0]; //tips: `h` only takes 1 byte in UTF8 format
assert_eq!(slice1, "h");
let slice2 = &s[3..5];// tips: `中` takes 3 bytes in UTF8 format
let slice2 = &s[3..5]; // Tips: `中` takes 3 bytes in UTF8 format
assert_eq!(slice2, "世");
// iterate all chars in s
// Iterate through all chars in s
for (i, c) in s.__ {
if i == 7 {
assert_eq!(c, '世')
}
}
println!("Success!")
println!("Success!");
}
```
#### utf8_slice
#### UTF8_slice
You can use [utf8_slice](https://docs.rs/utf8_slice/1.0.0/utf8_slice/fn.slice.html) to slice UTF8 string, it can index chars instead of bytes.
**Example**
@ -130,16 +130,16 @@ fn main() {
let mut s = String::new();
__;
// some bytes, in a vector
// Some bytes, in a vector
let v = vec![104, 101, 108, 108, 111];
// Turn a bytes vector into a String
// Turn a byte's vector into a String
let s1 = __;
assert_eq!(s, s1);
println!("Success!")
println!("Success!");
}
```
@ -151,7 +151,7 @@ The pointer points to an internal buffer String uses to store its data. The leng
6. 🌟🌟 If a String has enough capacity, adding elements to it will not re-allocate
```rust,editable
// modify the code below to print out:
// Modify the code below to print out:
// 25
// 25
// 25
@ -166,7 +166,7 @@ fn main() {
println!("{}", s.capacity());
}
println!("Success!")
println!("Success!");
}
```
@ -179,7 +179,7 @@ use std::mem;
fn main() {
let story = String::from("Rust By Practice");
// Prevent automatically dropping the String's data
// Prevent automatically dropping of the String's data
let mut story = mem::ManuallyDrop::new(story);
let ptr = story.__();
@ -188,14 +188,14 @@ fn main() {
assert_eq!(16, len);
// We can re-build a String out of ptr, len, and capacity. This is all
// We can rebuild a String out of ptr, len, and capacity. This is all
// unsafe because we are responsible for making sure the components are
// valid:
let s = unsafe { String::from_raw_parts(ptr, len, capacity) };
assert_eq!(*story, s);
println!("Success!")
println!("Success!");
}
```

View File

@ -1,5 +1,5 @@
# Vector
Vectors are re-sizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time.
Vectors are resizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time.
### Basic Operations
1. 🌟🌟🌟
@ -18,14 +18,14 @@ fn main() {
let v = vec!(1, 2, 3);
is_vec(v);
// in code below, v is Vec<[u8; 3]> , not Vec<u8>
// In code below, v is Vec<[u8; 3]> , not Vec<u8>
// USE Vec::new and `for` to rewrite the below code
let v1 = vec!(arr);
is_vec(v1);
assert_eq!(v, v1);
println!("Success!")
println!("Success!");
}
fn is_vec(v: Vec<u8>) {}
@ -33,7 +33,7 @@ fn is_vec(v: Vec<u8>) {}
2. 🌟🌟 a Vec can be extended with `extend` method
2. 🌟🌟 A Vec can be extended with `extend` method
```rust,editable
// FILL in the blank
@ -47,7 +47,7 @@ fn main() {
assert_eq!(v1, v2);
println!("Success!")
println!("Success!");
}
```
@ -57,7 +57,7 @@ fn main() {
// FILL in the blanks
fn main() {
// array -> Vec
// Array -> Vec
// impl From<[T; N]> for Vec
let arr = [1, 2, 3];
let v1 = __(arr);
@ -84,7 +84,7 @@ fn main() {
let v4: Vec<i32> = [0; 10].into_iter().collect();
assert_eq!(v4, vec![0; 10]);
println!("Success!")
println!("Success!");
}
```
@ -105,7 +105,7 @@ fn main() {
assert_eq!(v, vec![2, 3, 4, 5, 6]);
println!("Success!")
println!("Success!");
}
```
@ -123,13 +123,13 @@ fn main() {
let mut v = vec![1, 2, 3];
let slice1 = &v[..];
// out of bounds will cause a panic
// Out of bounds will cause a panic
// You must use `v.len` here
let slice2 = &v[0..4];
assert_eq!(slice1, slice2);
// slice are read only
// Slices are read only
// Note: slice and &Vec are different
let vec_ref: &mut Vec<i32> = &mut v;
(*vec_ref).push(4);
@ -138,7 +138,7 @@ fn main() {
assert_eq!(slice3, &[1, 2, 3, 4]);
println!("Success!")
println!("Success!");
}
```
### Capacity
@ -169,7 +169,7 @@ fn main() {
assert!(vec.capacity() >= 11);
// fill in an appropriate value to make the `for` done without reallocating
// Fill in an appropriate value to make the `for` done without reallocating
let mut vec = Vec::with_capacity(__);
for i in 0..100 {
vec.push(i);
@ -178,12 +178,12 @@ fn main() {
assert_eq!(vec.len(), __);
assert_eq!(vec.capacity(), __);
println!("Success!")
println!("Success!");
}
```
### Store distinct types in Vector
The elements in a vector mush be the same type, for example , the code below will cause an error:
The elements in a vector must be the same type, for example , the code below will cause an error:
```rust
fn main() {
let v = vec![1, 2.0, 3];
@ -207,7 +207,7 @@ fn main() {
assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));
assert_eq!(v[1], IpAddr::V6("::1".to_string()));
println!("Success!")
println!("Success!");
}
```