mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 12:39:42 +00:00
add en/string.md
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
# Summary
|
||||
|
||||
- [About Exercise.rs](why-exercise.md)
|
||||
- [Rust By Practice](why-exercise.md)
|
||||
- [Variables](variables.md)
|
||||
- [Basic Types](basic-types/intro.md)
|
||||
- [Numbers](basic-types/numbers.md)
|
||||
@ -10,12 +10,13 @@
|
||||
- [Ownership and Borrowing](ownership/intro.md)
|
||||
- [Ownership](ownership/ownership.md)
|
||||
- [Reference and Borrowing](ownership/borrowing.md)
|
||||
- [Compound Types todo](compound-types/intro.md)
|
||||
- [string and slice](compound-types/string-slice.md)
|
||||
- [tuple](compound-types/tuple.md)
|
||||
- [struct](compound-types/struct.md)
|
||||
- [enum](compound-types/enum.md)
|
||||
- [array](compound-types/array.md)
|
||||
- [Compound Types doing](compound-types/intro.md)
|
||||
- [string](compound-types/string.md)
|
||||
- [array todo](compound-types/array.md)
|
||||
- [slice todo](compound-types/slice.md)
|
||||
- [tuple todo](compound-types/tuple.md)
|
||||
- [struct todo](compound-types/struct.md)
|
||||
- [enum todo](compound-types/enum.md)
|
||||
- [Flow Control todo](flow-control.md)
|
||||
- [Pattern Match todo](pattern-match/intro.md)
|
||||
- [match, if let](pattern-match/match-iflet.md)
|
||||
|
@ -1 +1,6 @@
|
||||
# Compound Types
|
||||
Learning resources:
|
||||
- English: [Rust Book 4.3, 5.1, 6.1, 8.2](https://doc.rust-lang.org/book/ch04-03-slices.html)
|
||||
- 简体中文: [Rust语言圣经 - 复合类型](https://course.rs/basic/compound-type/intro.html)
|
||||
|
||||
|
||||
|
10
en/src/compound-types/slice.md
Normal file
10
en/src/compound-types/slice.md
Normal file
@ -0,0 +1,10 @@
|
||||
# slice todo
|
||||
|
||||
|
||||
```rust,editable
|
||||
// The trimmed string is a slice to the original string, hence no new
|
||||
// allocation is performed
|
||||
let chars_to_trim: &[char] = &[' ', ','];
|
||||
let trimmed_str: &str = string.trim_matches(chars_to_trim);
|
||||
println!("Used characters: {}", trimmed_str);
|
||||
```
|
@ -1 +0,0 @@
|
||||
# string and slice
|
285
en/src/compound-types/string.md
Normal file
285
en/src/compound-types/string.md
Normal file
@ -0,0 +1,285 @@
|
||||
# string
|
||||
The type of string literal `"hello, world"` is `&str`, e.g `let s: &str = "hello, world"`.
|
||||
|
||||
|
||||
### str and &str
|
||||
🌟 We can't use `str` type in normal ways, but we can use `&str`
|
||||
|
||||
```rust,editable
|
||||
|
||||
// fix error without adding new line
|
||||
fn main() {
|
||||
let s: str = "hello, world";
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
🌟🌟🌟 We can only use `str` by boxed it, `&` can be used to convert `Box<str>` to `&str`
|
||||
|
||||
```rust,editable
|
||||
|
||||
// fix error with at least two ways
|
||||
fn main() {
|
||||
let s: Box<str> = "hello, world".into();
|
||||
greetings(s)
|
||||
}
|
||||
|
||||
fn greetings(s: &str) {
|
||||
println!("{}",s)
|
||||
}
|
||||
```
|
||||
|
||||
### String
|
||||
`String` type is defined in std and stored as a vector of bytes (Vec<u8>), but guaranteed to always be a valid UTF-8 sequence. String is heap allocated, growable and not null terminated.
|
||||
|
||||
🌟
|
||||
```rust,editable
|
||||
|
||||
// fill the blank
|
||||
fn main() {
|
||||
let mut s = __;
|
||||
s.push_str("hello, world");
|
||||
s.push('!');
|
||||
|
||||
assert_eq!(s, "hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟🌟
|
||||
```rust,editable
|
||||
|
||||
// fix all errors without adding newline
|
||||
fn main() {
|
||||
let s = String::from("hello");
|
||||
s.push(',');`
|
||||
s.push(" world");
|
||||
s += "!".to_string();
|
||||
|
||||
println!("{}", s)
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟 `replace` can be used to replace substring
|
||||
```rust,editable
|
||||
|
||||
// fill the blank
|
||||
fn main() {
|
||||
let s = String::from("I like dogs");
|
||||
// Allocate new memory and store the modified string there
|
||||
let s1 = s.__("dogs", "cats");
|
||||
|
||||
assert_eq!(s1, "I like cats")
|
||||
}
|
||||
```
|
||||
|
||||
More `String` methods can be found under [String](https://doc.rust-lang.org/std/string/struct.String.html) module.
|
||||
|
||||
🌟🌟 You can only concat a `String` with `&str`, and `String`'s ownership can be moved to another variable
|
||||
|
||||
```rust,editable
|
||||
|
||||
// fix errors
|
||||
fn main() {
|
||||
let s1 = String::from("hello,");
|
||||
let s2 = String::from("world!");
|
||||
let s3 = s1 + s2;
|
||||
assert_eq!(s3,"hello,world!");
|
||||
println!("{}",s1);
|
||||
}
|
||||
```
|
||||
|
||||
### &str and String
|
||||
Opsite to the seldom using of `str`, `&str` and `String` are used everywhere!
|
||||
|
||||
🌟🌟 `&str` can be converted to `String` in two ways
|
||||
```rust,editable
|
||||
|
||||
// fix error with at lest two ways
|
||||
fn main() {
|
||||
let s = "hello, world";
|
||||
greetings(s)
|
||||
}
|
||||
|
||||
fn greetings(s: String) {
|
||||
println!("{}",s)
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟 We can use `String::from` or `to_string` to convert a `&str` to `String`
|
||||
|
||||
```rust,editable
|
||||
|
||||
// use two ways to fix error and without adding new line
|
||||
fn main() {
|
||||
let s = "hello, world".to_string();
|
||||
let s1: &str = s;
|
||||
}
|
||||
```
|
||||
|
||||
### string escapes
|
||||
🌟
|
||||
```rust,editable
|
||||
fn main() {
|
||||
// You can use escapes to write bytes by their hexadecimal values
|
||||
// fill the blank below to show "I'm writing Rust"
|
||||
let byte_escape = "I'm writing Ru\x73__!";
|
||||
println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);
|
||||
|
||||
// ...or Unicode code points.
|
||||
let unicode_codepoint = "\u{211D}";
|
||||
let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";
|
||||
|
||||
println!("Unicode character {} (U+211D) is called {}",
|
||||
unicode_codepoint, character_name );
|
||||
|
||||
let long_string = "String literals
|
||||
can span multiple lines.
|
||||
The linebreak and indentation here \
|
||||
can be escaped too!";
|
||||
println!("{}", long_string);
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟 Sometimes there are just too many characters that need to be escaped or it's just much more convenient to write a string out as-is. This is where raw string literals come into play.
|
||||
|
||||
```rust,editable
|
||||
|
||||
fn main() {
|
||||
let raw_str = r"Escapes don't work here: \x3F \u{211D}";
|
||||
println!("{}", raw_str);
|
||||
|
||||
// If you need quotes in a raw string, add a pair of #s
|
||||
let quotes = r#"And then I said: "There is no escape!""#;
|
||||
println!("{}", quotes);
|
||||
|
||||
// If you need "# in your string, just use more #s in the delimiter.
|
||||
// You can use up to 65535 #s.
|
||||
let longer_delimiter = r###"A string with "# in it. And even "##!"###;
|
||||
println!("{}", longer_delimiter);
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟🌟
|
||||
```rust,editable
|
||||
|
||||
fn main() {
|
||||
let raw_str = r"Escapes don't work here: \x3F \u{211D}";
|
||||
// modify below line to make it work
|
||||
assert_eq!(raw_str, "Escapes don't work here: ? ℝ");
|
||||
|
||||
// If you need quotes in a raw string, add a pair of #s
|
||||
let quotes = r#"And then I said: "There is no escape!""#;
|
||||
println!("{}", quotes);
|
||||
|
||||
// If you need "# in your string, just use more #s in the delimiter.
|
||||
// You can use up to 65535 #s.
|
||||
let delimiter = r###"A string with "# in it. And even "##!"###;
|
||||
println!("{}", delimiter);
|
||||
|
||||
// fill the blank
|
||||
let long_delimiter = __;
|
||||
assert_eq!(long_delimiter, "Hello, \"##\"")
|
||||
}
|
||||
```
|
||||
|
||||
### byte string
|
||||
Want a string that's not UTF-8? (Remember, str and String must be valid UTF-8). Or maybe you want an array of bytes that's mostly text? Byte strings to the rescue!
|
||||
|
||||
**Example**:
|
||||
```rust,editable
|
||||
use std::str;
|
||||
|
||||
fn main() {
|
||||
// Note that this is not actually a `&str`
|
||||
let bytestring: &[u8; 21] = b"this is a byte string";
|
||||
|
||||
// Byte arrays don't have the `Display` trait, so printing them is a bit limited
|
||||
println!("A byte string: {:?}", bytestring);
|
||||
|
||||
// Byte strings can have byte escapes...
|
||||
let escaped = b"\x52\x75\x73\x74 as bytes";
|
||||
// ...but no unicode escapes
|
||||
// let escaped = b"\u{211D} is not allowed";
|
||||
println!("Some escaped bytes: {:?}", escaped);
|
||||
|
||||
|
||||
// Raw byte strings work just like raw strings
|
||||
let raw_bytestring = br"\u{211D} is not escaped here";
|
||||
println!("{:?}", raw_bytestring);
|
||||
|
||||
// Converting a byte array to `str` can fail
|
||||
if let Ok(my_str) = str::from_utf8(raw_bytestring) {
|
||||
println!("And the same as text: '{}'", my_str);
|
||||
}
|
||||
|
||||
let _quotes = br#"You can also use "fancier" formatting, \
|
||||
like with normal raw strings"#;
|
||||
|
||||
// Byte strings don't have to be UTF-8
|
||||
let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // "ようこそ" in SHIFT-JIS
|
||||
|
||||
// But then they can't always be converted to `str`
|
||||
match str::from_utf8(shift_jis) {
|
||||
Ok(my_str) => println!("Conversion successful: '{}'", my_str),
|
||||
Err(e) => println!("Conversion failed: {:?}", e),
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
A more detailed listing of the ways to write string literals and escape characters is given in the ['Tokens' chapter](https://doc.rust-lang.org/reference/tokens.html) of the Rust Reference.
|
||||
|
||||
### string index
|
||||
🌟🌟 You can't use index to access a char in a string, but you can use slice `&s1[start..end]`.
|
||||
|
||||
```rust,editable
|
||||
|
||||
fn main() {
|
||||
let s1 = String::from("hi,中国");
|
||||
let h = s1[0]; //modify this line to fix the error, tips: `h` only takes 1 byte in UTF8 format
|
||||
assert_eq!(h, "h");
|
||||
|
||||
let h1 = &s1[3..5];//modify this line to fix the error, tips: `中` takes 3 bytes in UTF8 format
|
||||
assert_eq!(h1, "中");
|
||||
}
|
||||
```
|
||||
|
||||
### operate on UTF8 string
|
||||
🌟
|
||||
```rust,editable
|
||||
|
||||
fn main() {
|
||||
// fill the blank to print each char in "你好,世界"
|
||||
for c in "你好,世界".__ {
|
||||
println!("{}", c)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
🌟🌟
|
||||
```rust,editable
|
||||
use utf8_slice;
|
||||
|
||||
fn main() {
|
||||
let s = "The 🚀 goes to the 🌑!";
|
||||
|
||||
let rocket = utf8_slice::slice(s, 4, 5);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 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**
|
||||
```rust
|
||||
use utf_slice;
|
||||
fn main() {
|
||||
let s = "The 🚀 goes to the 🌑!";
|
||||
|
||||
let rocket = utf8_slice::slice(s, 4, 5);
|
||||
// Will equal "🚀"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
@ -1 +1,19 @@
|
||||
# Iterator
|
||||
|
||||
```rust,editable
|
||||
// (all the type annotations are superfluous)
|
||||
// A reference to a string allocated in read only memory
|
||||
let pangram: &'static str = "the quick brown fox jumps over the lazy dog";
|
||||
println!("Pangram: {}", pangram);
|
||||
|
||||
// Iterate over words in reverse, no new string is allocated
|
||||
println!("Words in reverse");
|
||||
for word in pangram.split_whitespace().rev() {
|
||||
println!("> {}", word);
|
||||
}
|
||||
|
||||
// Copy chars into a vector, sort and remove duplicates
|
||||
let mut chars: Vec<char> = pangram.chars().collect();
|
||||
chars.sort();
|
||||
chars.dedup();
|
||||
```
|
@ -1,8 +1,8 @@
|
||||
# Rust By Practice
|
||||
|
||||
> 中文版[传送门](https://zh.exercise.rs)
|
||||
> 中文版[传送门](https://zh.practice.rs)
|
||||
|
||||
- Online Reading: [https://exercise.rs](https://exercise.rs)
|
||||
- Online Reading: [https://practice.rs](https://practice.rs)
|
||||
|
||||
Greetings Rustaceans and welcome here, if you have the following problems:
|
||||
|
||||
@ -37,13 +37,13 @@ If you are a first-time Rust learner, here are some high quality learning resour
|
||||
Another limit for rustlings is that you have to download rustlings to local machine and compile it first before starting to learn.
|
||||
|
||||
## difference to rust by example
|
||||
[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) is an excellent online book for learning Rust,`exercise.rs` has some small advantages in :
|
||||
[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) is an excellent online book for learning Rust,`practice.rs` has some small advantages in :
|
||||
|
||||
- more topics and exercises,specially for the hard part of Rust,e.g lifetime、smart pointers、threads 、async/.await etc
|
||||
- difficulty from easy to hard,it will minimize the gap between learning and using in projects
|
||||
- up-to-date, e.g features which added in Rust 1.58 also have the corresponding exercises in `exercise.rs`
|
||||
- Both `course.rs` and `exercise.rs` are designed according to the CS courses in college,so quliaty is the most important factor
|
||||
|
||||
- up-to-date, e.g features which added in Rust 1.58 also have the corresponding exercises in `practice.rs`
|
||||
- Both `course.rs` and `practice.rs` are designed according to the CS courses in college,so quliaty is the most important factor
|
||||
- real practice
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user