diff --git a/Readme.md b/Readme.md index abf06f2..be86c95 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # Rust By Practice ([中文 Readme](./zh-CN/Readme.md)) -- 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: @@ -39,7 +39,7 @@ Another limit for rustlings is that you have to download rustlings to local mach - 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.59 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 practices diff --git a/en/assets/CNAME b/en/assets/CNAME index 2c5ea12..c6cd02a 100644 --- a/en/assets/CNAME +++ b/en/assets/CNAME @@ -1 +1 @@ -exercise.rs \ No newline at end of file +practice.rs \ No newline at end of file diff --git a/en/book.toml b/en/book.toml index 7ec5b17..5dfb368 100644 --- a/en/book.toml +++ b/en/book.toml @@ -1,6 +1,6 @@ [book] -title = "Rust Exercise" -description = "A set of exercises and examples to pratice various aspects of Rust, also for the rust course (book) at https://course.rs" +title = "Rust By Practice" +description = "Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team" authors = ["sunface, https://im.dev"] language = "en" @@ -13,8 +13,8 @@ enable = true level = 1 [output.html] -git-repository-url = "https://github.com/sunface/rust-exercise" -edit-url-template = "https://github.com/sunface/rust-exercise/edit/master/en/{path}" +git-repository-url = "https://github.com/sunface/rust-by-practice" +edit-url-template = "https://github.com/sunface/rust-by-practice/edit/master/en/{path}" [rust] edition = "2021" \ No newline at end of file diff --git a/en/deploy b/en/deploy index c1c7896..bc03d24 100755 --- a/en/deploy +++ b/en/deploy @@ -15,7 +15,7 @@ git config user.email "cto@188.com" git add . git commit -m 'deploy' git branch -M gh-pages -git remote add origin https://github.com/sunface/rust-exercise +git remote add origin https://github.com/sunface/rust-by-practice ## push to github pages git push -u -f origin gh-pages \ No newline at end of file diff --git a/en/src/SUMMARY.md b/en/src/SUMMARY.md index e2bd8f2..63dc734 100644 --- a/en/src/SUMMARY.md +++ b/en/src/SUMMARY.md @@ -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) diff --git a/en/src/compound-types/intro.md b/en/src/compound-types/intro.md index 0c35451..c67d6fa 100644 --- a/en/src/compound-types/intro.md +++ b/en/src/compound-types/intro.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) + + diff --git a/en/src/compound-types/slice.md b/en/src/compound-types/slice.md new file mode 100644 index 0000000..7d24c91 --- /dev/null +++ b/en/src/compound-types/slice.md @@ -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); +``` \ No newline at end of file diff --git a/en/src/compound-types/string.md b/en/src/compound-types/string.md new file mode 100644 index 0000000..f253aab --- /dev/null +++ b/en/src/compound-types/string.md @@ -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` to `&str` + +```rust,editable + +// fix error with at least two ways +fn main() { + let s: Box = "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), 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 "🚀" +} +``` + + + diff --git a/en/src/functional-programing/iterator.md b/en/src/functional-programing/iterator.md index 2a4a2aa..68ae1d7 100644 --- a/en/src/functional-programing/iterator.md +++ b/en/src/functional-programing/iterator.md @@ -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 = pangram.chars().collect(); +chars.sort(); +chars.dedup(); +``` \ No newline at end of file diff --git a/en/src/why-exercise.md b/en/src/why-exercise.md index 39f24c5..1ca176d 100644 --- a/en/src/why-exercise.md +++ b/en/src/why-exercise.md @@ -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 diff --git a/zh-CN/Readme.md b/zh-CN/Readme.md index c348339..278043b 100644 --- a/zh-CN/Readme.md +++ b/zh-CN/Readme.md @@ -1,8 +1,8 @@ # Rust By Practice -- English: [https://exercise.rs](https://exercise.rs) -- 简体中文: [https://zh.exercise.rs](https://zh.exercise.rs) +- English: [https://practice.rs](https://practice.rs) +- 简体中文: [https://zh.practice.rs](https://zh.practice.rs) -欢迎大家来到 `exercise.rs`,在来到这里之前不知道你有没有碰到过以下问题: +欢迎大家来到 `practice.rs`,在来到这里之前不知道你有没有碰到过以下问题: - 学完知识,想要针对性的练习,但是只能找到一些不痛不痒的习题 - 一些 Rust 工具、标准库等相关的习题更是一个都找不到 @@ -21,7 +21,7 @@ ## 学习 Rust 语言 我们强烈推荐在开始做练习之前,先看看 [<>]((https://course.rs)) 这本书,它覆盖了从入门到精通所需的全部知识,相信我,里面绝对有你所需要的 Rust 知识。 -(悄咪咪的告诉咱中国用户, `exercise.rs` 章节目录和 <> 完全相同,大家猜猜为什么) +(悄咪咪的告诉咱中国用户, `practice.rs` 章节目录和 <> 完全相同,大家猜猜为什么) @@ -32,10 +32,10 @@ 另一个问题就是 rustlings 需要先下载到本地,然后编译运行,无法在线使用。 ## 对比 Rust By Example -[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) 是相当不错的在线练习题,相比之前,`exercise.rs` 拥有以下优势 : +[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) 是相当不错的在线练习题,相比之前,`practice.rs` 拥有以下优势 : - 内容覆盖面更广,且练习题更多、针对性更强,充分满足大家做题的快乐 - 难度从简单到困难都有,且更贴合实际 - 跟随 Rust 版本实时更新, -- `course.rs` 和 `exercise.rs` 看域名就知道,它非常有信心才敢使用这两个针对性如此之强的域名,而信心来源于**高质量** - +- `course.rs` 和 `practice.rs` 看域名就知道,它非常有信心才敢使用这两个针对性如此之强的域名,而信心来源于**高质量** +- 实践应用 \ No newline at end of file diff --git a/zh-CN/assets/CNAME b/zh-CN/assets/CNAME index d893176..ffc44bc 100644 --- a/zh-CN/assets/CNAME +++ b/zh-CN/assets/CNAME @@ -1 +1 @@ -zh.exercise.rs \ No newline at end of file +zh.practice.rs \ No newline at end of file diff --git a/zh-CN/book.toml b/zh-CN/book.toml index 75b13d7..591d652 100644 --- a/zh-CN/book.toml +++ b/zh-CN/book.toml @@ -1,6 +1,6 @@ [book] -title = "Rust Exercise" -description = "A set of exercises and examples to pratice various aspects of Rust, also for the rust course (book) at https://course.rs" +title = "Rust By Practice( Rust 练习实践 )" +description = "Practice Rust with example, exercise and hand-to-hand projects. Written with ❤️ by https://course.rs team" authors = ["sunface, https://im.dev"] language = "en" @@ -13,8 +13,8 @@ enable = true level = 1 [output.html] -git-repository-url = "https://github.com/sunface/rust-exercise" -edit-url-template = "https://github.com/sunface/rust-exercise/edit/master/zh-CN/{path}" +git-repository-url = "https://github.com/sunface/rust-by-practice" +edit-url-template = "https://github.com/sunface/rust-by-practice/edit/master/zh-CN/{path}" [rust] edition = "2021" \ No newline at end of file diff --git a/zh-CN/deploy b/zh-CN/deploy index 88bf719..0294c20 100755 --- a/zh-CN/deploy +++ b/zh-CN/deploy @@ -15,7 +15,7 @@ git config user.email "cto@188.com" git add . git commit -m 'deploy' git branch -M gh-pages -git remote add origin https://github.com/sunface/zh.exercise.rs +git remote add origin https://github.com/sunface/zh.practice.rs ## push to github pages git push -u -f origin gh-pages \ No newline at end of file diff --git a/zh-CN/src/SUMMARY.md b/zh-CN/src/SUMMARY.md index bf84423..08c6871 100644 --- a/zh-CN/src/SUMMARY.md +++ b/zh-CN/src/SUMMARY.md @@ -1,6 +1,6 @@ # Summary -- [关于 exercise.rs](why-exercise.md) +- [关于 pracitce.rs](why-exercise.md) - [变量绑定与解构](variables.md) - [基本类型](basic-types/intro.md) - [数值类型](basic-types/numbers.md) @@ -11,11 +11,12 @@ - [所有权](ownership/ownership.md) - [引用和借用](ownership/borrowing.md) - [复合类型 todo](compound-types/intro.md) - - [字符串与切片](compound-types/string-slice.md) + - [字符串](compound-types/string.md) + - [数组](compound-types/array.md) + - [切片](compound-types/slice.md) - [元组](compound-types/tuple.md) - [结构体](compound-types/struct.md) - [枚举](compound-types/enum.md) - - [数组](compound-types/array.md) - [流程控制 todo](flow-control.md) - [模式匹配 todo](pattern-match/intro.md) - [match 和 if let](pattern-match/match-iflet.md) diff --git a/zh-CN/src/compound-types/string-slice.md b/zh-CN/src/compound-types/string-slice.md deleted file mode 100644 index 9f17363..0000000 --- a/zh-CN/src/compound-types/string-slice.md +++ /dev/null @@ -1 +0,0 @@ -# string and slice diff --git a/en/src/compound-types/string-slice.md b/zh-CN/src/compound-types/string.md similarity index 100% rename from en/src/compound-types/string-slice.md rename to zh-CN/src/compound-types/string.md diff --git a/zh-CN/src/why-exercise.md b/zh-CN/src/why-exercise.md index 704929c..af7927a 100644 --- a/zh-CN/src/why-exercise.md +++ b/zh-CN/src/why-exercise.md @@ -1,7 +1,7 @@ # Rust By Practice -> 英文版 [传送门](https://exercise.rs) +> 英文版 [传送门](https://practice.rs) -欢迎大家来到 `exercise.rs`,在来到这里之前不知道你有没有碰到过以下问题: +欢迎大家来到 `practice.rs`,在来到这里之前不知道你有没有碰到过以下问题: - 学完知识,想要针对性的练习,但是只能找到一些不痛不痒的习题 - 一些 Rust 工具、标准库等相关的习题更是一个都找不到 @@ -11,8 +11,8 @@ ## 在线阅读 本书同时提供了中文和英文版本: -- English: [https://exercise.rs](https://exercise.rs) -- 简体中文: [https://zh.exercise.rs](https://zh.exercise.rs) +- English: [https://practice.rs](https://exercise.rs) +- 简体中文: [https://zh.practice.rs](https://zh.exercise.rs) ## 关于练习题的说明 - 一切都在线化: 阅读、编辑和测试代码,当然还包括错误提示 @@ -25,7 +25,7 @@ ## 学习 Rust 语言 我们强烈推荐在开始做练习之前,先看看 [<>]((https://course.rs)) 这本书,它覆盖了从入门到精通所需的全部知识,相信我,里面绝对有你所需要的 Rust 知识。 -(悄咪咪的告诉咱中国用户, `exercise.rs` 章节目录和 <> 完全相同,大家猜猜为什么) +(悄咪咪的告诉咱中国用户, `practice.rs` 章节目录和 <> 完全相同,大家猜猜为什么) @@ -36,12 +36,13 @@ 另一个问题就是 rustlings 需要先下载到本地,然后编译运行,无法在线使用。 ## 对比 Rust By Example -[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) 是相当不错的在线练习题,相比之前,`exercise.rs` 拥有以下优势 : +[Rust By Example](https://doc.rust-lang.org/stable/rust-by-example/) 是相当不错的在线练习题,相比之前,`practice.rs` 拥有以下优势 : - 内容覆盖面更广,且练习题更多、针对性更强,充分满足大家做题的快乐 - 难度从简单到困难都有,且更贴合实际 - 跟随 Rust 版本实时更新, -- `course.rs` 和 `exercise.rs` 看域名就知道,它非常有信心才敢使用这两个针对性如此之强的域名,而信心来源于**高质量** +- `course.rs` 和 `practice.rs` 看域名就知道,它非常有信心才敢使用这两个针对性如此之强的域名,而信心来源于**高质量** +- 应用实践