From 2aaae6f4d26925459d9dcc87cb1ec1d7f942f4b0 Mon Sep 17 00:00:00 2001 From: Unisko PENG Date: Tue, 11 Apr 2023 17:17:17 +0800 Subject: [PATCH] reorganized the directories --- projects/add/Cargo.toml | 6 + projects/add/add_one/Cargo.toml | 9 + projects/add/add_one/src/lib.rs | 14 + projects/add/adder/Cargo.toml | 10 + projects/add/adder/src/main.rs | 6 + projects/adder/Cargo.toml | 8 + projects/adder/src/lib.rs | 17 + projects/adder/tests/common/mod.rs | 3 + projects/adder/tests/integration_test.rs | 9 + projects/aggregator/Cargo.toml | 8 + projects/aggregator/src/bin/test_case.rs | 3 + projects/aggregator/src/lib.rs | 56 +++ projects/aggregator/src/main.rs | 54 +++ projects/art/Cargo.toml | 8 + projects/art/src/kinds.rs | 15 + projects/art/src/lib.rs | 10 + projects/art/src/utils.rs | 9 + projects/assert_demo/Cargo.toml | 8 + projects/assert_demo/src/lib.rs | 43 +++ projects/associated_type/Cargo.toml | 8 + projects/associated_type/src/main.rs | 3 + projects/branches/Cargo.toml | 8 + projects/branches/src/main.rs | 7 + projects/cargo_features_demo/Cargo.toml | 9 + projects/cargo_features_demo/src/lib.rs | 21 ++ projects/cargo_features_demo/src/main.rs | 8 + projects/cargo_features_demo/src/tests.rs | 6 + projects/clippy_demo/Cargo.toml | 8 + projects/clippy_demo/src/main.rs | 5 + projects/closure-example/Cargo.toml | 8 + projects/closure-example/src/main.rs | 22 ++ projects/closure_demo/Cargo.toml | 8 + projects/closure_demo/src/main.rs | 57 ++++ projects/concur_demo/Cargo.toml | 8 + projects/concur_demo/src/main.rs | 14 + projects/cons_list_demo/Cargo.toml | 8 + projects/cons_list_demo/src/main.rs | 24 ++ projects/declarative_macro/Cargo.toml | 8 + projects/declarative_macro/src/main.rs | 4 + projects/derive_macro_comsumer/Cargo.toml | 10 + projects/derive_macro_comsumer/src/main.rs | 9 + projects/disambiguation/Cargo.toml | 8 + projects/disambiguation/src/main.rs | 21 ++ projects/dst/Cargo.toml | 8 + projects/dst/src/main.rs | 4 + projects/encapsulation_demo/Cargo.toml | 8 + projects/encapsulation_demo/src/lib.rs | 34 ++ projects/enum_demo/Cargo.toml | 8 + projects/enum_demo/src/main.rs | 7 + projects/error_handling_demo/Cargo.toml | 8 + projects/error_handling_demo/src/main.rs | 9 + projects/extern_code/Cargo.toml | 8 + projects/extern_code/src/main.rs | 17 + projects/fah_to_cels/Cargo.toml | 8 + projects/fah_to_cels/src/main.rs | 67 ++++ projects/fn_pattn_demo/Cargo.toml | 8 + projects/fn_pattn_demo/src/main.rs | 8 + projects/for_demo/Cargo.toml | 8 + projects/for_demo/src/main.rs | 7 + projects/func_pointer/Cargo.toml | 8 + projects/func_pointer/src/main.rs | 30 ++ projects/functions/Cargo.toml | 8 + projects/functions/src/main.rs | 9 + projects/generics_demo/Cargo.toml | 8 + projects/generics_demo/src/main.rs | 14 + projects/guessing_game/Cargo.toml | 11 + projects/guessing_game/README.md | 3 + projects/guessing_game/src/main.rs | 64 ++++ projects/hashmap_demo/Cargo.toml | 8 + projects/hashmap_demo/src/main.rs | 14 + projects/hello/404.html | 11 + projects/hello/Cargo.toml | 8 + projects/hello/hello.html | 11 + projects/hello/src/lib.rs | 92 +++++ projects/hello/src/main.rs | 46 +++ projects/hello_cargo/Cargo.toml | 8 + projects/hello_cargo/src/main.rs | 4 + projects/hello_macro/Cargo.toml | 8 + .../hello_macro/hello_macro_derive/Cargo.toml | 12 + .../hello_macro/hello_macro_derive/src/lib.rs | 26 ++ projects/hello_macro/src/lib.rs | 3 + projects/hello_macro_derive/Cargo.toml | 8 + projects/hello_macro_derive/src/lib.rs | 14 + projects/hello_world/Cargo.toml | 8 + projects/hello_world/src/main.rs | 4 + projects/if_let_demo/Cargo.toml | 8 + projects/if_let_demo/src/main.rs | 22 ++ projects/iterator_demo/Cargo.toml | 8 + projects/iterator_demo/src/lib.rs | 35 ++ projects/iterator_demo/src/main.rs | 7 + projects/iterator_demo/src/tests.rs | 35 ++ projects/lifetimes_demo/Cargo.toml | 8 + projects/lifetimes_demo/src/main.rs | 23 ++ projects/limit_tracker/Cargo.toml | 8 + projects/limit_tracker/src/lib.rs | 77 +++++ projects/loops/Cargo.toml | 8 + projects/loops/src/main.rs | 7 + projects/lyrics_of_xmas_carol/Cargo.toml | 8 + projects/lyrics_of_xmas_carol/src/main.rs | 60 ++++ projects/minigrep/Cargo.toml | 14 + projects/minigrep/poem.txt | 9 + projects/minigrep/src/data_structures.rs | 33 ++ projects/minigrep/src/lib.rs | 57 ++++ projects/minigrep/src/main.rs | 19 ++ projects/minigrep/src/tests.rs | 28 ++ projects/mp_demo/Cargo.toml | 8 + projects/mp_demo/src/main.rs | 43 +++ projects/mutex_demo/Cargo.toml | 8 + projects/mutex_demo/src/main.rs | 27 ++ projects/neo_simple_blog/Cargo.toml | 8 + projects/neo_simple_blog/src/lib.rs | 43 +++ projects/neo_simple_blog/src/main.rs | 15 + projects/never_type/Cargo.toml | 8 + projects/never_type/src/main.rs | 7 + projects/newtype/Cargo.toml | 8 + projects/newtype/src/main.rs | 13 + projects/nth_fibonacci/Cargo.toml | 9 + projects/nth_fibonacci/src/main.rs | 47 +++ projects/operator_overloading/Cargo.toml | 8 + projects/operator_overloading/src/main.rs | 45 +++ projects/ownership_demo/Cargo.toml | 8 + projects/ownership_demo/src/main.rs | 42 +++ projects/pattern_syntax_demo/Cargo.toml | 8 + projects/pattern_syntax_demo/src/main.rs | 17 + projects/raw_idenitifers/Cargo.toml | 8 + projects/raw_idenitifers/src/main.rs | 7 + projects/raw_pointers/Cargo.toml | 8 + projects/raw_pointers/src/main.rs | 11 + projects/rectangles/Cargo.toml | 8 + projects/rectangles/src/main.rs | 52 +++ projects/ref_cycle_demo/Cargo.toml | 8 + projects/ref_cycle_demo/src/main.rs | 42 +++ projects/references_demo/Cargo.toml | 8 + projects/references_demo/src/main.rs | 11 + projects/refutable_demo/Cargo.toml | 8 + projects/refutable_demo/src/main.rs | 5 + projects/restaurant/Cargo.toml | 8 + projects/restaurant/src/front_of_house.rs | 1 + .../restaurant/src/front_of_house/hosting.rs | 1 + projects/restaurant/src/lib.rs | 28 ++ projects/returning_closure/Cargo.toml | 8 + projects/returning_closure/src/main.rs | 7 + projects/rustfix_demo/Cargo.toml | 8 + projects/rustfix_demo/src/main.rs | 7 + projects/safe_abstraction/Cargo.toml | 8 + projects/safe_abstraction/src/main.rs | 12 + projects/simple_blog/Cargo.toml | 8 + projects/simple_blog/src/lib.rs | 82 +++++ projects/simple_blog/src/main.rs | 17 + projects/simple_gui/Cargo.toml | 8 + projects/simple_gui/src/lib.rs | 31 ++ projects/simple_gui/src/main.rs | 27 ++ projects/sp_demos/Cargo.toml | 8 + projects/sp_demos/src/main.rs | 4 + projects/static_variable/Cargo.toml | 8 + projects/static_variable/src/main.rs | 15 + projects/string_demo/Cargo.toml | 8 + projects/string_demo/src/main.rs | 11 + projects/structs_demo/Cargo.toml | 8 + projects/supertrait/Cargo.toml | 8 + projects/supertrait/src/main.rs | 32 ++ projects/theme/index.hbs | 319 ++++++++++++++++++ projects/theme/pagetoc.css | 62 ++++ projects/theme/pagetoc.js | 49 +++ projects/traits_demo/src/aggregator/lib.rs | 29 ++ projects/tree_demo/Cargo.toml | 8 + projects/tree_demo/src/main.rs | 51 +++ projects/type_aliases/Cargo.toml | 8 + projects/type_aliases/src/main.rs | 20 ++ projects/unsafe_functions/Cargo.toml | 8 + projects/unsafe_functions/src/main.rs | 7 + projects/unsafe_trait/Cargo.toml | 8 + projects/unsafe_trait/src/main.rs | 9 + projects/variables/Cargo.toml | 8 + projects/variables/src/main.rs | 29 ++ projects/vec_demo/Cargo.toml | 8 + projects/vec_demo/src/main.rs | 26 ++ projects/while_let_demo/Cargo.toml | 8 + projects/while_let_demo/src/main.rs | 5 + src/Ch21_Appendix.md | 34 +- 180 files changed, 3325 insertions(+), 1 deletion(-) create mode 100644 projects/add/Cargo.toml create mode 100644 projects/add/add_one/Cargo.toml create mode 100644 projects/add/add_one/src/lib.rs create mode 100644 projects/add/adder/Cargo.toml create mode 100644 projects/add/adder/src/main.rs create mode 100644 projects/adder/Cargo.toml create mode 100644 projects/adder/src/lib.rs create mode 100644 projects/adder/tests/common/mod.rs create mode 100644 projects/adder/tests/integration_test.rs create mode 100644 projects/aggregator/Cargo.toml create mode 100644 projects/aggregator/src/bin/test_case.rs create mode 100644 projects/aggregator/src/lib.rs create mode 100644 projects/aggregator/src/main.rs create mode 100644 projects/art/Cargo.toml create mode 100644 projects/art/src/kinds.rs create mode 100644 projects/art/src/lib.rs create mode 100644 projects/art/src/utils.rs create mode 100644 projects/assert_demo/Cargo.toml create mode 100644 projects/assert_demo/src/lib.rs create mode 100644 projects/associated_type/Cargo.toml create mode 100644 projects/associated_type/src/main.rs create mode 100644 projects/branches/Cargo.toml create mode 100644 projects/branches/src/main.rs create mode 100644 projects/cargo_features_demo/Cargo.toml create mode 100644 projects/cargo_features_demo/src/lib.rs create mode 100644 projects/cargo_features_demo/src/main.rs create mode 100644 projects/cargo_features_demo/src/tests.rs create mode 100644 projects/clippy_demo/Cargo.toml create mode 100644 projects/clippy_demo/src/main.rs create mode 100644 projects/closure-example/Cargo.toml create mode 100644 projects/closure-example/src/main.rs create mode 100644 projects/closure_demo/Cargo.toml create mode 100644 projects/closure_demo/src/main.rs create mode 100644 projects/concur_demo/Cargo.toml create mode 100644 projects/concur_demo/src/main.rs create mode 100644 projects/cons_list_demo/Cargo.toml create mode 100644 projects/cons_list_demo/src/main.rs create mode 100644 projects/declarative_macro/Cargo.toml create mode 100644 projects/declarative_macro/src/main.rs create mode 100644 projects/derive_macro_comsumer/Cargo.toml create mode 100644 projects/derive_macro_comsumer/src/main.rs create mode 100644 projects/disambiguation/Cargo.toml create mode 100644 projects/disambiguation/src/main.rs create mode 100644 projects/dst/Cargo.toml create mode 100644 projects/dst/src/main.rs create mode 100644 projects/encapsulation_demo/Cargo.toml create mode 100644 projects/encapsulation_demo/src/lib.rs create mode 100644 projects/enum_demo/Cargo.toml create mode 100644 projects/enum_demo/src/main.rs create mode 100644 projects/error_handling_demo/Cargo.toml create mode 100644 projects/error_handling_demo/src/main.rs create mode 100644 projects/extern_code/Cargo.toml create mode 100644 projects/extern_code/src/main.rs create mode 100644 projects/fah_to_cels/Cargo.toml create mode 100644 projects/fah_to_cels/src/main.rs create mode 100644 projects/fn_pattn_demo/Cargo.toml create mode 100644 projects/fn_pattn_demo/src/main.rs create mode 100644 projects/for_demo/Cargo.toml create mode 100644 projects/for_demo/src/main.rs create mode 100644 projects/func_pointer/Cargo.toml create mode 100644 projects/func_pointer/src/main.rs create mode 100644 projects/functions/Cargo.toml create mode 100644 projects/functions/src/main.rs create mode 100644 projects/generics_demo/Cargo.toml create mode 100644 projects/generics_demo/src/main.rs create mode 100644 projects/guessing_game/Cargo.toml create mode 100644 projects/guessing_game/README.md create mode 100644 projects/guessing_game/src/main.rs create mode 100644 projects/hashmap_demo/Cargo.toml create mode 100644 projects/hashmap_demo/src/main.rs create mode 100644 projects/hello/404.html create mode 100644 projects/hello/Cargo.toml create mode 100644 projects/hello/hello.html create mode 100644 projects/hello/src/lib.rs create mode 100644 projects/hello/src/main.rs create mode 100644 projects/hello_cargo/Cargo.toml create mode 100644 projects/hello_cargo/src/main.rs create mode 100644 projects/hello_macro/Cargo.toml create mode 100644 projects/hello_macro/hello_macro_derive/Cargo.toml create mode 100644 projects/hello_macro/hello_macro_derive/src/lib.rs create mode 100644 projects/hello_macro/src/lib.rs create mode 100644 projects/hello_macro_derive/Cargo.toml create mode 100644 projects/hello_macro_derive/src/lib.rs create mode 100644 projects/hello_world/Cargo.toml create mode 100644 projects/hello_world/src/main.rs create mode 100644 projects/if_let_demo/Cargo.toml create mode 100644 projects/if_let_demo/src/main.rs create mode 100644 projects/iterator_demo/Cargo.toml create mode 100644 projects/iterator_demo/src/lib.rs create mode 100644 projects/iterator_demo/src/main.rs create mode 100644 projects/iterator_demo/src/tests.rs create mode 100644 projects/lifetimes_demo/Cargo.toml create mode 100644 projects/lifetimes_demo/src/main.rs create mode 100644 projects/limit_tracker/Cargo.toml create mode 100644 projects/limit_tracker/src/lib.rs create mode 100644 projects/loops/Cargo.toml create mode 100644 projects/loops/src/main.rs create mode 100644 projects/lyrics_of_xmas_carol/Cargo.toml create mode 100644 projects/lyrics_of_xmas_carol/src/main.rs create mode 100644 projects/minigrep/Cargo.toml create mode 100644 projects/minigrep/poem.txt create mode 100644 projects/minigrep/src/data_structures.rs create mode 100644 projects/minigrep/src/lib.rs create mode 100644 projects/minigrep/src/main.rs create mode 100644 projects/minigrep/src/tests.rs create mode 100644 projects/mp_demo/Cargo.toml create mode 100644 projects/mp_demo/src/main.rs create mode 100644 projects/mutex_demo/Cargo.toml create mode 100644 projects/mutex_demo/src/main.rs create mode 100644 projects/neo_simple_blog/Cargo.toml create mode 100644 projects/neo_simple_blog/src/lib.rs create mode 100644 projects/neo_simple_blog/src/main.rs create mode 100644 projects/never_type/Cargo.toml create mode 100644 projects/never_type/src/main.rs create mode 100644 projects/newtype/Cargo.toml create mode 100644 projects/newtype/src/main.rs create mode 100644 projects/nth_fibonacci/Cargo.toml create mode 100644 projects/nth_fibonacci/src/main.rs create mode 100644 projects/operator_overloading/Cargo.toml create mode 100644 projects/operator_overloading/src/main.rs create mode 100644 projects/ownership_demo/Cargo.toml create mode 100644 projects/ownership_demo/src/main.rs create mode 100644 projects/pattern_syntax_demo/Cargo.toml create mode 100644 projects/pattern_syntax_demo/src/main.rs create mode 100644 projects/raw_idenitifers/Cargo.toml create mode 100644 projects/raw_idenitifers/src/main.rs create mode 100644 projects/raw_pointers/Cargo.toml create mode 100644 projects/raw_pointers/src/main.rs create mode 100644 projects/rectangles/Cargo.toml create mode 100644 projects/rectangles/src/main.rs create mode 100644 projects/ref_cycle_demo/Cargo.toml create mode 100644 projects/ref_cycle_demo/src/main.rs create mode 100644 projects/references_demo/Cargo.toml create mode 100644 projects/references_demo/src/main.rs create mode 100644 projects/refutable_demo/Cargo.toml create mode 100644 projects/refutable_demo/src/main.rs create mode 100644 projects/restaurant/Cargo.toml create mode 100644 projects/restaurant/src/front_of_house.rs create mode 100644 projects/restaurant/src/front_of_house/hosting.rs create mode 100644 projects/restaurant/src/lib.rs create mode 100644 projects/returning_closure/Cargo.toml create mode 100644 projects/returning_closure/src/main.rs create mode 100644 projects/rustfix_demo/Cargo.toml create mode 100644 projects/rustfix_demo/src/main.rs create mode 100644 projects/safe_abstraction/Cargo.toml create mode 100644 projects/safe_abstraction/src/main.rs create mode 100644 projects/simple_blog/Cargo.toml create mode 100644 projects/simple_blog/src/lib.rs create mode 100644 projects/simple_blog/src/main.rs create mode 100644 projects/simple_gui/Cargo.toml create mode 100644 projects/simple_gui/src/lib.rs create mode 100644 projects/simple_gui/src/main.rs create mode 100644 projects/sp_demos/Cargo.toml create mode 100644 projects/sp_demos/src/main.rs create mode 100644 projects/static_variable/Cargo.toml create mode 100644 projects/static_variable/src/main.rs create mode 100644 projects/string_demo/Cargo.toml create mode 100644 projects/string_demo/src/main.rs create mode 100644 projects/structs_demo/Cargo.toml create mode 100644 projects/supertrait/Cargo.toml create mode 100644 projects/supertrait/src/main.rs create mode 100644 projects/theme/index.hbs create mode 100644 projects/theme/pagetoc.css create mode 100644 projects/theme/pagetoc.js create mode 100644 projects/traits_demo/src/aggregator/lib.rs create mode 100644 projects/tree_demo/Cargo.toml create mode 100644 projects/tree_demo/src/main.rs create mode 100644 projects/type_aliases/Cargo.toml create mode 100644 projects/type_aliases/src/main.rs create mode 100644 projects/unsafe_functions/Cargo.toml create mode 100644 projects/unsafe_functions/src/main.rs create mode 100644 projects/unsafe_trait/Cargo.toml create mode 100644 projects/unsafe_trait/src/main.rs create mode 100644 projects/variables/Cargo.toml create mode 100644 projects/variables/src/main.rs create mode 100644 projects/vec_demo/Cargo.toml create mode 100644 projects/vec_demo/src/main.rs create mode 100644 projects/while_let_demo/Cargo.toml create mode 100644 projects/while_let_demo/src/main.rs diff --git a/projects/add/Cargo.toml b/projects/add/Cargo.toml new file mode 100644 index 0000000..1448801 --- /dev/null +++ b/projects/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/projects/add/add_one/Cargo.toml b/projects/add/add_one/Cargo.toml new file mode 100644 index 0000000..66ee46a --- /dev/null +++ b/projects/add/add_one/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "^0.8.4" diff --git a/projects/add/add_one/src/lib.rs b/projects/add/add_one/src/lib.rs new file mode 100644 index 0000000..8eff881 --- /dev/null +++ b/projects/add/add_one/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add_one(x: i32) -> i32 { + x + 1 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add_one(2); + assert_eq!(result, 3); + } +} diff --git a/projects/add/adder/Cargo.toml b/projects/add/adder/Cargo.toml new file mode 100644 index 0000000..5ff08a7 --- /dev/null +++ b/projects/add/adder/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +add_one = { path = "../add_one" } +rand = "0.8.4" diff --git a/projects/add/adder/src/main.rs b/projects/add/adder/src/main.rs new file mode 100644 index 0000000..b4153a8 --- /dev/null +++ b/projects/add/adder/src/main.rs @@ -0,0 +1,6 @@ +use add_one::add_one; + +fn main() { + let num = 10; + println!("你好,世界!\n\t{num} 加 1 为 {}!", add_one(num)); +} diff --git a/projects/adder/Cargo.toml b/projects/adder/Cargo.toml new file mode 100644 index 0000000..b7d36d4 --- /dev/null +++ b/projects/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/adder/src/lib.rs b/projects/adder/src/lib.rs new file mode 100644 index 0000000..c1d0c22 --- /dev/null +++ b/projects/adder/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_add(a, 2) +} + +fn internal_add(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq! (4, internal_add(2, 2)); + } +} diff --git a/projects/adder/tests/common/mod.rs b/projects/adder/tests/common/mod.rs new file mode 100644 index 0000000..503f4f8 --- /dev/null +++ b/projects/adder/tests/common/mod.rs @@ -0,0 +1,3 @@ +pub fn setup() { + println! ("特定于库测试的一些设置代码,将放在这里"); +} diff --git a/projects/adder/tests/integration_test.rs b/projects/adder/tests/integration_test.rs new file mode 100644 index 0000000..c56ed2c --- /dev/null +++ b/projects/adder/tests/integration_test.rs @@ -0,0 +1,9 @@ +use adder; + +mod common; + +#[test] +fn it_adds_two() { + common::setup(); + assert_eq! (6, adder::add_two(4)); +} diff --git a/projects/aggregator/Cargo.toml b/projects/aggregator/Cargo.toml new file mode 100644 index 0000000..27d4889 --- /dev/null +++ b/projects/aggregator/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/aggregator/src/bin/test_case.rs b/projects/aggregator/src/bin/test_case.rs new file mode 100644 index 0000000..3b69746 --- /dev/null +++ b/projects/aggregator/src/bin/test_case.rs @@ -0,0 +1,3 @@ +fn main() { + println! ("媒体聚合器"); +} diff --git a/projects/aggregator/src/lib.rs b/projects/aggregator/src/lib.rs new file mode 100644 index 0000000..16246ae --- /dev/null +++ b/projects/aggregator/src/lib.rs @@ -0,0 +1,56 @@ +pub trait Summary { + fn summarize_author(&self) -> String; + + fn summarize(&self) -> String { + format! ("(了解更多来自 {} ......)", self.summarize_author()) + } +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize_author(&self) -> String { + format! ("{}", self.author) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize_author(&self) -> String { + format! ("@{}", self.username) + } +} + +use std::fmt::Display; + +pub struct Pair { + pub x: T, + pub y: T, +} + +impl Pair { + pub fn new(x: T, y: T) -> Self { + Self { x, y } + } +} + +impl Pair { + pub fn cmp_display(&self) { + if self.x >= self.y { + println! ("极大数为 x = {}", self.x); + } else { + println! ("极大数为 y = {}", self.y); + } + } +} diff --git a/projects/aggregator/src/main.rs b/projects/aggregator/src/main.rs new file mode 100644 index 0000000..1828013 --- /dev/null +++ b/projects/aggregator/src/main.rs @@ -0,0 +1,54 @@ +use aggregator::{Summary, Tweet, NewsArticle, Pair}; + +pub fn notify(item: &T) { + println! ("突发新闻!{}", item.summarize()); +} + +fn return_summarizable() -> impl Summary { + Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "当然,如同你或许已经知道的一样,朋友们" + ), + reply: false, + retweet: false, + } +} + +fn main() { + let tweet = Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "当然,跟大家已经清楚的一样了,朋友们", + ), + reply: false, + retweet: false, + }; + + println!("1 条新推文: {}", tweet.summarize()); + notify(&tweet); + + + let article = NewsArticle { + headline: String::from("企鹅队赢得斯坦利杯锦标赛!"), + location: String::from("美国,宾夕法尼亚州,匹兹堡"), + author: String::from("Iceburgh"), + content: String::from( + "匹兹堡企鹅队再度成为美国曲棍球联盟 \ + NHL 中的最佳球队。" + ), + }; + + println! ("有新文章可读!{}", article.summarize()); + notify(&article); + + println! ("1 条旧推文: {}", return_summarizable().summarize()); + + let pair = Pair::new(5, 10); + pair.cmp_display(); + + let pair = Pair::new("这是一个测试", "This is a test."); + pair.cmp_display(); + + println! ("{}", 3.to_string()); +} diff --git a/projects/art/Cargo.toml b/projects/art/Cargo.toml new file mode 100644 index 0000000..4742a18 --- /dev/null +++ b/projects/art/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "art" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/art/src/kinds.rs b/projects/art/src/kinds.rs new file mode 100644 index 0000000..d5a9a30 --- /dev/null +++ b/projects/art/src/kinds.rs @@ -0,0 +1,15 @@ +/// RYB 颜色模型下的主要颜色。 +#[derive(Debug)] +pub enum PrimaryColor { + Red, + Yellow, + Blue, +} + +/// RYB 颜色模型下的次要颜色。 +#[derive(Debug)] +pub enum SecondaryColor { + Orange, + Green, + Purple, +} diff --git a/projects/art/src/lib.rs b/projects/art/src/lib.rs new file mode 100644 index 0000000..1c2ee79 --- /dev/null +++ b/projects/art/src/lib.rs @@ -0,0 +1,10 @@ +//! # art - 美术 +//! +//! 建模诸多美术概念的一个库。 + +pub mod kinds; +pub mod utils; + +pub use self::kinds::PrimaryColor; +pub use self::kinds::SecondaryColor; +pub use self::utils::mix; diff --git a/projects/art/src/utils.rs b/projects/art/src/utils.rs new file mode 100644 index 0000000..8de81af --- /dev/null +++ b/projects/art/src/utils.rs @@ -0,0 +1,9 @@ +use crate::kinds::*; + +/// 结合两种等量的主要颜色,创建出 +/// 某种次要颜色。 +pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { + // --跳过代码-- + println! ("c1: {:?}, c2: {:?}", c1, c2); + SecondaryColor::Purple +} diff --git a/projects/assert_demo/Cargo.toml b/projects/assert_demo/Cargo.toml new file mode 100644 index 0000000..3e4fdc2 --- /dev/null +++ b/projects/assert_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "assert_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/assert_demo/src/lib.rs b/projects/assert_demo/src/lib.rs new file mode 100644 index 0000000..4a2898b --- /dev/null +++ b/projects/assert_demo/src/lib.rs @@ -0,0 +1,43 @@ +pub fn add_two(a: i32) -> i32 { + a + 2 +} + +pub fn nth_fibonacci(n: u64) -> u64 { + + if n == 0 || n == 1 { + return n; + } else { + return nth_fibonacci(n - 1) + nth_fibonacci(n - 2); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_two_and_two() { + assert_eq! (4, add_two(2)); + } + + #[test] + fn add_three_and_two() { + assert_eq! (5, add_two(3)); + } + + #[test] + fn one_hundred() { + assert_eq! (102, add_two(100)); + } + + #[test] + fn it_works() { + assert_eq! (2 + 2, 4); + } + + #[test] + #[ignore] + fn expensive_test() { + assert_ne! (100, nth_fibonacci(50)); + } +} diff --git a/projects/associated_type/Cargo.toml b/projects/associated_type/Cargo.toml new file mode 100644 index 0000000..4e9eec7 --- /dev/null +++ b/projects/associated_type/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "associated_type" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/associated_type/src/main.rs b/projects/associated_type/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/projects/associated_type/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/projects/branches/Cargo.toml b/projects/branches/Cargo.toml new file mode 100644 index 0000000..6934aa4 --- /dev/null +++ b/projects/branches/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/branches/src/main.rs b/projects/branches/src/main.rs new file mode 100644 index 0000000..d09ae5c --- /dev/null +++ b/projects/branches/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let condition = true; + + let number = if condition { 5 } else { "six" }; + + println! ("number 的值为:{}", number); +} diff --git a/projects/cargo_features_demo/Cargo.toml b/projects/cargo_features_demo/Cargo.toml new file mode 100644 index 0000000..2a540a2 --- /dev/null +++ b/projects/cargo_features_demo/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "cargo_features_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +art = { path = "../art" } diff --git a/projects/cargo_features_demo/src/lib.rs b/projects/cargo_features_demo/src/lib.rs new file mode 100644 index 0000000..98097dd --- /dev/null +++ b/projects/cargo_features_demo/src/lib.rs @@ -0,0 +1,21 @@ +//! # Cargo 特性示例代码箱 +//! +//! `cargo_features_demo` 是令到执行某些确切计算更便利 +//! 的一些工具的集合。 +//! + +/// 将一加到所给数字。 +/// # 示例(examples) +/// +/// ``` +/// let arg = 5; +/// let answer = cargo_features_demo::add_one(arg); +/// +/// assert_eq! (6, answer); +/// ``` +pub fn add_one(x: i32) -> i32 { + x + 2 +} + +#[cfg(test)] +mod tests; diff --git a/projects/cargo_features_demo/src/main.rs b/projects/cargo_features_demo/src/main.rs new file mode 100644 index 0000000..170a783 --- /dev/null +++ b/projects/cargo_features_demo/src/main.rs @@ -0,0 +1,8 @@ +use art::mix; +use art::PrimaryColor; + +fn main() { + let red = PrimaryColor::Red; + let yellow = PrimaryColor::Yellow; + mix(red, yellow); +} diff --git a/projects/cargo_features_demo/src/tests.rs b/projects/cargo_features_demo/src/tests.rs new file mode 100644 index 0000000..b65c49d --- /dev/null +++ b/projects/cargo_features_demo/src/tests.rs @@ -0,0 +1,6 @@ +use super::*; + +#[test] +fn five_plus_one() { + assert_eq! (7, add_one(5)); +} diff --git a/projects/clippy_demo/Cargo.toml b/projects/clippy_demo/Cargo.toml new file mode 100644 index 0000000..0d357fe --- /dev/null +++ b/projects/clippy_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "clippy_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/clippy_demo/src/main.rs b/projects/clippy_demo/src/main.rs new file mode 100644 index 0000000..8f4c0b9 --- /dev/null +++ b/projects/clippy_demo/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let x = std::f64::consts::PI; + let r = 8.0; + println!("圆的面积为 {}", x * r * r); +} diff --git a/projects/closure-example/Cargo.toml b/projects/closure-example/Cargo.toml new file mode 100644 index 0000000..8085ade --- /dev/null +++ b/projects/closure-example/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "closure-example" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/closure-example/src/main.rs b/projects/closure-example/src/main.rs new file mode 100644 index 0000000..0c514f5 --- /dev/null +++ b/projects/closure-example/src/main.rs @@ -0,0 +1,22 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let mut list = [ + Rectangle { width: 10, height: 1 }, + Rectangle { width: 3, height: 5 }, + Rectangle { width: 7, height: 12 }, + ]; + + let mut sort_operations = vec! []; + let value = String::from("按照被调用到的 key"); + + list.sort_by_key(|r| { + sort_operations.push(&value); + r.width + }); + println! ("{:#?}\n{:#?}", list, sort_operations); +} diff --git a/projects/closure_demo/Cargo.toml b/projects/closure_demo/Cargo.toml new file mode 100644 index 0000000..643b4d5 --- /dev/null +++ b/projects/closure_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "closure_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/closure_demo/src/main.rs b/projects/closure_demo/src/main.rs new file mode 100644 index 0000000..974f605 --- /dev/null +++ b/projects/closure_demo/src/main.rs @@ -0,0 +1,57 @@ +#[derive(Debug, PartialEq, Copy, Clone)] +enum ShirtColor { + Red, + Blue, +} + +struct Inventory { + shirts: Vec, +} + +impl Inventory { + fn giveaway( + &self, + user_preference: Option + ) -> ShirtColor { + user_preference.unwrap_or_else(|| self.most_stocked()) + } + + fn most_stocked(&self) -> ShirtColor { + let mut num_red = 0; + let mut num_blue = 0; + + for color in &self.shirts { + match color { + ShirtColor::Red => num_red += 1, + ShirtColor::Blue => num_blue += 1, + } + } + + if num_red > num_blue { + ShirtColor::Red + } else { + ShirtColor::Blue + } + } +} + +fn main() { + let store = Inventory { + shirts: vec! [ShirtColor::Blue, ShirtColor::Red, ShirtColor::Blue], + }; + + let user_pref1 = Some(ShirtColor::Red); + let giveaway1 = store.giveaway(user_pref1); + println! ( + "选项为 {:?} 的用户,得到了 {:?}", + user_pref1, giveaway1 + ); + + let user_pref2 = None; + let giveaway2 = store.giveaway(user_pref2); + println! ( + "选项为 {:?} 的用户得到了 {:?}", + user_pref2, giveaway2 + ); + +} diff --git a/projects/concur_demo/Cargo.toml b/projects/concur_demo/Cargo.toml new file mode 100644 index 0000000..53aebaa --- /dev/null +++ b/projects/concur_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "concur_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/concur_demo/src/main.rs b/projects/concur_demo/src/main.rs new file mode 100644 index 0000000..886d3ec --- /dev/null +++ b/projects/concur_demo/src/main.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::thread; + +fn main() { + let v = vec! [1, 2, 3]; + + let handle = thread::spawn(move || { + println! ("这里有个矢量值:{:?}", &v); + }); + + handle.join().unwrap(); +} diff --git a/projects/cons_list_demo/Cargo.toml b/projects/cons_list_demo/Cargo.toml new file mode 100644 index 0000000..d9b7875 --- /dev/null +++ b/projects/cons_list_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "cons_list_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/cons_list_demo/src/main.rs b/projects/cons_list_demo/src/main.rs new file mode 100644 index 0000000..3a8bc3e --- /dev/null +++ b/projects/cons_list_demo/src/main.rs @@ -0,0 +1,24 @@ +#[derive(Debug)] +enum List { + Cons(Rc>, Rc), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +fn main() { + let value = Rc::new(RefCell::new(5)); + + let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); + + let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); + let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); + + *value.borrow_mut() += 10; + + println! ("之后的 a = {:?}", a); + println! ("之后的 b = {:?}", b); + println! ("之后的 c = {:?}", c); +} diff --git a/projects/declarative_macro/Cargo.toml b/projects/declarative_macro/Cargo.toml new file mode 100644 index 0000000..aa308b2 --- /dev/null +++ b/projects/declarative_macro/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "declarative_macro" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/declarative_macro/src/main.rs b/projects/declarative_macro/src/main.rs new file mode 100644 index 0000000..65f6504 --- /dev/null +++ b/projects/declarative_macro/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + + println!("Hello, world!"); +} diff --git a/projects/derive_macro_comsumer/Cargo.toml b/projects/derive_macro_comsumer/Cargo.toml new file mode 100644 index 0000000..b7ff214 --- /dev/null +++ b/projects/derive_macro_comsumer/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "derive_macro_comsumer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hello_macro = { path = "../hello_macro" } +hello_macro_derive = { path = "../hello_macro/hello_macro_derive" } diff --git a/projects/derive_macro_comsumer/src/main.rs b/projects/derive_macro_comsumer/src/main.rs new file mode 100644 index 0000000..468c30a --- /dev/null +++ b/projects/derive_macro_comsumer/src/main.rs @@ -0,0 +1,9 @@ +use hello_macro::HelloMacro; +use hello_macro_derive::HelloMacro; + +#[derive(HelloMacro)] +struct Pancakes; + +fn main() { + Pancakes::hello_macro(); +} diff --git a/projects/disambiguation/Cargo.toml b/projects/disambiguation/Cargo.toml new file mode 100644 index 0000000..2fc552b --- /dev/null +++ b/projects/disambiguation/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "disambiguation" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/disambiguation/src/main.rs b/projects/disambiguation/src/main.rs new file mode 100644 index 0000000..a715029 --- /dev/null +++ b/projects/disambiguation/src/main.rs @@ -0,0 +1,21 @@ +trait Animal { + fn baby_name() -> String; +} + +struct Dog; + +impl Dog { + fn baby_name() -> String { + String::from("点点") + } +} + +impl Animal for Dog { + fn baby_name() -> String { + String::from("狗崽") + } +} + +fn main() { + println! ("小狗叫做 {}", ::baby_name()); +} diff --git a/projects/dst/Cargo.toml b/projects/dst/Cargo.toml new file mode 100644 index 0000000..5d1f188 --- /dev/null +++ b/projects/dst/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "dst" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/dst/src/main.rs b/projects/dst/src/main.rs new file mode 100644 index 0000000..19bcaab --- /dev/null +++ b/projects/dst/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let s1: str = "致以问候!"; + let s2: str = "最近过得怎么样?"; +} diff --git a/projects/encapsulation_demo/Cargo.toml b/projects/encapsulation_demo/Cargo.toml new file mode 100644 index 0000000..d463a97 --- /dev/null +++ b/projects/encapsulation_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "encapsulation_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/encapsulation_demo/src/lib.rs b/projects/encapsulation_demo/src/lib.rs new file mode 100644 index 0000000..3fc846c --- /dev/null +++ b/projects/encapsulation_demo/src/lib.rs @@ -0,0 +1,34 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +pub struct AveragedCollection { + list: Vec, + average: f64, +} + +impl AveragedCollection { + pub fn add(&mut self, value: i32) { + self.list.push(value); + self.update_average(); + } + + pub fn remove(&mut self) -> Option { + let result = self.list.pop(); + match result { + Some(value) => { + self.update_average(); + Some(value) + } + None => None, + } + } + + pub fn average(&self) -> f64 { + self.average + } + + fn update_average(&mut self) { + let total: i32 = self.list.iter().sum(); + self.average = total as f64 / self.list.len() as f64; + } +} diff --git a/projects/enum_demo/Cargo.toml b/projects/enum_demo/Cargo.toml new file mode 100644 index 0000000..5cbbd5e --- /dev/null +++ b/projects/enum_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "enum_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/enum_demo/src/main.rs b/projects/enum_demo/src/main.rs new file mode 100644 index 0000000..0af60c3 --- /dev/null +++ b/projects/enum_demo/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let config_max: Option = Some(3u8); + + if let Option::Some(max) = (config_max) { + println! ("极大值被设置为了 {}", max); + } +} diff --git a/projects/error_handling_demo/Cargo.toml b/projects/error_handling_demo/Cargo.toml new file mode 100644 index 0000000..3a161fe --- /dev/null +++ b/projects/error_handling_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "error_handling_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/error_handling_demo/src/main.rs b/projects/error_handling_demo/src/main.rs new file mode 100644 index 0000000..230c217 --- /dev/null +++ b/projects/error_handling_demo/src/main.rs @@ -0,0 +1,9 @@ +fn main () { + use std::net::IpAddr; + + let home: IpAddr = "192.168.0.255" + .parse() + .expect("硬编码的 IP 地址应是有效的"); + + println! ("{}", home); +} diff --git a/projects/extern_code/Cargo.toml b/projects/extern_code/Cargo.toml new file mode 100644 index 0000000..a271a5f --- /dev/null +++ b/projects/extern_code/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "extern_code" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/extern_code/src/main.rs b/projects/extern_code/src/main.rs new file mode 100644 index 0000000..cfbfcce --- /dev/null +++ b/projects/extern_code/src/main.rs @@ -0,0 +1,17 @@ +extern "C" { + fn abs(input: i32) -> i32; + fn sqrt(input: f64) -> f64; +} + + +#[no_mangle] +pub extern "C" fn call_from_c() { + println! ("刚从 C 调用了一个 Rust 函数!"); +} + +fn main() { + unsafe { + println! ("C 语言中 -3 的绝对值为:{},3.0 的平方根为:{}", abs(-3), sqrt(3.0)); + } +} + diff --git a/projects/fah_to_cels/Cargo.toml b/projects/fah_to_cels/Cargo.toml new file mode 100644 index 0000000..a4be573 --- /dev/null +++ b/projects/fah_to_cels/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fah_to_cels" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/fah_to_cels/src/main.rs b/projects/fah_to_cels/src/main.rs new file mode 100644 index 0000000..af6d21f --- /dev/null +++ b/projects/fah_to_cels/src/main.rs @@ -0,0 +1,67 @@ +use std::io; +use std::process; + +fn fah_to_cels(f: f32) -> f32 { + return (f - 32.0) / 1.8; +} + +fn cels_to_fah(c: f32) -> f32 { + return c * 1.8 + 32.0; +} + +fn main() { + println! ("法式温度与摄氏温度之间的转换"); + + loop { + println! ("\n-----------------\n请选择: + '1'-摄氏温度/'2'-法式温度/'Q'/\"quit\" 退出程序。 + '1'/'2'/'Q'/\"quit\"[1]:"); + + let mut temp_type = String::new(); + + io::stdin() + .read_line(&mut temp_type) + .expect("读取输入失败!"); + + let temp_type = temp_type.trim(); + + if temp_type.eq("Q") || temp_type.eq("quit") { process::exit(0); } + + if ! temp_type.eq("1") && ! temp_type.eq("2") && ! temp_type.eq("") { + println! ("无效输入,请输入 '1'、'2'、'Q'、\"quit\",或直接按下回车键"); + continue; + } + + if temp_type.eq("1") || temp_type.eq("") { + println! ("请输入要转换的摄氏温度:"); + let temp = get_temp_input(); + + println! ("摄氏温度: {:.2}°C,约为法氏温度:{:.2}°F", temp, cels_to_fah(temp)); + } + + if temp_type.eq("2") { + println! ("请输入要转换的法氏温度:"); + let temp = get_temp_input(); + + println! ("法氏温度:{:.2}°F,约为摄氏温度:{:.2}°C", temp, fah_to_cels(temp)); + } + } +} + +fn get_temp_input() -> f32 { + return loop { + let mut tmp = String::new(); + + io::stdin() + .read_line(&mut tmp) + .expect("读取输入失败"); + + match tmp.trim().parse() { + Ok(num) => { break num }, + Err(_) => { + println! ("请输入一个浮点数,比如 -10.0, 15.6"); + continue + } + }; + }; +} diff --git a/projects/fn_pattn_demo/Cargo.toml b/projects/fn_pattn_demo/Cargo.toml new file mode 100644 index 0000000..1e72a95 --- /dev/null +++ b/projects/fn_pattn_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fn_pattn_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/fn_pattn_demo/src/main.rs b/projects/fn_pattn_demo/src/main.rs new file mode 100644 index 0000000..0fe2f3b --- /dev/null +++ b/projects/fn_pattn_demo/src/main.rs @@ -0,0 +1,8 @@ +fn print_coordinates(&(x, y): &(i32, i32)) { + println!("当前坐标:({}, {})", x, y); +} + +fn main() { + let point = (3, -5); + print_coordinates(&point); +} diff --git a/projects/for_demo/Cargo.toml b/projects/for_demo/Cargo.toml new file mode 100644 index 0000000..fac497a --- /dev/null +++ b/projects/for_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "for_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/for_demo/src/main.rs b/projects/for_demo/src/main.rs new file mode 100644 index 0000000..14f624c --- /dev/null +++ b/projects/for_demo/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let v = vec! ['a', 'b', 'c']; + + for (index, value) in v.iter().enumerate() { + println! ("{} 处于索引 {} 处", value, index); + } +} diff --git a/projects/func_pointer/Cargo.toml b/projects/func_pointer/Cargo.toml new file mode 100644 index 0000000..0758072 --- /dev/null +++ b/projects/func_pointer/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "func_pointer" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/func_pointer/src/main.rs b/projects/func_pointer/src/main.rs new file mode 100644 index 0000000..b17345c --- /dev/null +++ b/projects/func_pointer/src/main.rs @@ -0,0 +1,30 @@ +fn add_one(x: i32) -> i32 { + x + 1 +} + +fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { + f(arg) + f(arg) +} + + +fn main() { + let answer = do_twice(add_one, 5); + + println! ("答案为:{}", answer); + + let list_of_numbers = vec! [1, 2, 3]; + let list_of_strings: Vec = + list_of_numbers.iter().map(ToString::to_string).collect(); + + println! ("结果为:{:?}", list_of_strings); + + #[derive(Debug)] + enum Status { + Value(u32), + Stop, + } + + let mut list_of_statuses: Vec = (0u32..20).map(Status::Value).collect(); + list_of_statuses.append(&mut vec! [Status::Stop]); + println! ("list_of_statuses: {:?}", list_of_statuses); +} diff --git a/projects/functions/Cargo.toml b/projects/functions/Cargo.toml new file mode 100644 index 0000000..a9b5578 --- /dev/null +++ b/projects/functions/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/functions/src/main.rs b/projects/functions/src/main.rs new file mode 100644 index 0000000..a79372c --- /dev/null +++ b/projects/functions/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x = plus_one(-1); + + println! ("x 的值为:{}", x); +} + +fn plus_one(x: i32) -> i32 { + x + 1 +} diff --git a/projects/generics_demo/Cargo.toml b/projects/generics_demo/Cargo.toml new file mode 100644 index 0000000..8974a0e --- /dev/null +++ b/projects/generics_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "generics_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/generics_demo/src/main.rs b/projects/generics_demo/src/main.rs new file mode 100644 index 0000000..d25919a --- /dev/null +++ b/projects/generics_demo/src/main.rs @@ -0,0 +1,14 @@ +enum Option_i32 { + Some(i32), + None, +} + +enum Option_f64 { + Some(f64), + None, +} + +fn main() { + let integer = Option_i32::Some(5); + let float = Option_f64::Some(5.0); +} diff --git a/projects/guessing_game/Cargo.toml b/projects/guessing_game/Cargo.toml new file mode 100644 index 0000000..80f0a08 --- /dev/null +++ b/projects/guessing_game/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "guessing_game-xfossdotcom" +license = "MIT" +version = "0.1.1" +description = "一个在其中猜出计算机所选数字的有趣游戏。" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/projects/guessing_game/README.md b/projects/guessing_game/README.md new file mode 100644 index 0000000..610c66e --- /dev/null +++ b/projects/guessing_game/README.md @@ -0,0 +1,3 @@ +# Readme + +这是一个作为把代码箱上传到 [crates.io](https://crates.io) 示例的 Rust 项目。 diff --git a/projects/guessing_game/src/main.rs b/projects/guessing_game/src/main.rs new file mode 100644 index 0000000..79837d3 --- /dev/null +++ b/projects/guessing_game/src/main.rs @@ -0,0 +1,64 @@ +use rand::Rng; +use std::{cmp::Ordering, io, process}; + +pub struct Guess { + value: i32, +} + +impl Guess { + pub fn new(value: i32) -> Guess { + if value < 1 || value > 100 { + panic! ("Guess 类型值必须在 1 与 100 之间,收到的是 {}", value); + } + + Guess { value } + } + + pub fn value(&self) -> i32 { + self.value + } +} + +fn main() { + loop { + println! ("\n---猜出这个数来!---"); + + let secret_number: i32 = rand::thread_rng().gen_range(1..101); + + // println! ("随机生成的秘密数字为:{}", secret_number); + + loop { + println! ("请输入你猜的数。( ‘Q/quit’ 退出游戏)"); + + let mut guess: String = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("读取行失败......"); + + if guess.trim().eq("Q") || guess.trim().eq("quit") { process::exit(0); } + + // let guess: u32 = guess.trim().parse().expect("请输入一个数字!"); + let guess: i32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => { println! ("请输入一个数字!"); continue }, + }; + + if guess < 1 || guess > 100 { + println! ("秘密数字将在 1 和 100 之间"); + continue + } + + println! ("你猜的数为:{}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println! ("太小了!"), + Ordering::Greater => println! ("太大了!"), + Ordering::Equal => { + println! ("你赢了!"); + break + }, + } + } + } +} diff --git a/projects/hashmap_demo/Cargo.toml b/projects/hashmap_demo/Cargo.toml new file mode 100644 index 0000000..c948a8c --- /dev/null +++ b/projects/hashmap_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hashmap_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hashmap_demo/src/main.rs b/projects/hashmap_demo/src/main.rs new file mode 100644 index 0000000..dcaf432 --- /dev/null +++ b/projects/hashmap_demo/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + use std::collections::HashMap; + + let text = "hello world wonderful world"; + + let mut map = HashMap::new(); + + for word in text.split_whitespace() { + let count = map.entry(word).or_insert(0); + *count += 1; + } + + println! ("{:?}", map); +} diff --git a/projects/hello/404.html b/projects/hello/404.html new file mode 100644 index 0000000..49c36b1 --- /dev/null +++ b/projects/hello/404.html @@ -0,0 +1,11 @@ + + + + + 你好! + + +

糟糕!

+

抱歉,我不明白你要什么。

+ + diff --git a/projects/hello/Cargo.toml b/projects/hello/Cargo.toml new file mode 100644 index 0000000..fb1ec2c --- /dev/null +++ b/projects/hello/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hello/hello.html b/projects/hello/hello.html new file mode 100644 index 0000000..b3d914e --- /dev/null +++ b/projects/hello/hello.html @@ -0,0 +1,11 @@ + + + + + 你好! + + +

你好!

+

来自 Rust 的问好

+ + diff --git a/projects/hello/src/lib.rs b/projects/hello/src/lib.rs new file mode 100644 index 0000000..78e7e53 --- /dev/null +++ b/projects/hello/src/lib.rs @@ -0,0 +1,92 @@ +use std::{ + sync::{mpsc, Arc, Mutex}, + thread, +}; + +pub struct ThreadPool { + workers: Vec, + sender: Option>, +} + +type Job = Box; + +impl ThreadPool { + /// 创建出一个新的 ThreadPool。 + /// + /// 其中的 size 为线程池中线程的数目。 + /// + /// # 终止运行 + /// + /// 这个 `new` 函数将在 size 为零时终止运行。 + pub fn new(size: usize) -> ThreadPool { + assert! (size > 0); + + let (sender, receiver) = mpsc::channel(); + + let receiver = Arc::new(Mutex::new(receiver)); + + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id, Arc::clone(&receiver))); + } + + ThreadPool { + workers, + sender: Some(sender), + } + } + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + let job = Box::new(f); + + self.sender.as_ref().unwrap().send(job).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + drop(self.sender.take()); + + for worker in &mut self.workers { + println! ("关闭 worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv(); + + match message { + Ok(job) => { + println! ("Worker {id} 获取到一项作业;执行中。"); + + job(); + } + Err(_) => { + println! ("Worker {id} 已断开链接;关闭中。"); + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/projects/hello/src/main.rs b/projects/hello/src/main.rs new file mode 100644 index 0000000..b1fcbe2 --- /dev/null +++ b/projects/hello/src/main.rs @@ -0,0 +1,46 @@ +use hello::ThreadPool; + +use std::{ + fs, + thread, + io::{prelude::*, BufReader}, + net::{TcpListener, TcpStream}, + time::Duration, +}; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + let pool = ThreadPool::new(4); + + for stream in listener.incoming().take(2) { + let stream = stream.unwrap(); + + pool.execute(|| { + handle_conn(stream); + }); + } + + println! ("关闭中。"); +} + +fn handle_conn(mut stream: TcpStream) { + let buf_reader = BufReader::new(&mut stream); + let req_line = buf_reader.lines().next().unwrap().unwrap(); + + let (status_line, filename) = match &req_line[..] { + "GET / HTTP/1.1" => ( "HTTP/1.1 200 OK", "hello.html"), + "GET /sleep HTTP/1.1" => { + thread::sleep(Duration::from_secs(10)); + ("HTTP/1.1 200 0K", "hello.html") + } + _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), + }; + + let contents = fs::read_to_string(filename).unwrap(); + let length = contents.len(); + + let resp = + format! ("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); + + stream.write_all(resp.as_bytes()).unwrap(); +} diff --git a/projects/hello_cargo/Cargo.toml b/projects/hello_cargo/Cargo.toml new file mode 100644 index 0000000..19c7b36 --- /dev/null +++ b/projects/hello_cargo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_cargo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hello_cargo/src/main.rs b/projects/hello_cargo/src/main.rs new file mode 100644 index 0000000..bfb0e05 --- /dev/null +++ b/projects/hello_cargo/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + // 这是注释。 + println! ("Hello, Cargo!"); +} diff --git a/projects/hello_macro/Cargo.toml b/projects/hello_macro/Cargo.toml new file mode 100644 index 0000000..9b9d479 --- /dev/null +++ b/projects/hello_macro/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hello_macro/hello_macro_derive/Cargo.toml b/projects/hello_macro/hello_macro_derive/Cargo.toml new file mode 100644 index 0000000..1b02fb9 --- /dev/null +++ b/projects/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +proc-macro = true + +[dependencies] +syn = "1.0" +quote = "1.0" diff --git a/projects/hello_macro/hello_macro_derive/src/lib.rs b/projects/hello_macro/hello_macro_derive/src/lib.rs new file mode 100644 index 0000000..e45a413 --- /dev/null +++ b/projects/hello_macro/hello_macro_derive/src/lib.rs @@ -0,0 +1,26 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn; + +#[proc_macro_derive(HelloMacro)] +pub fn hello_macro_derive(input: TokenStream) -> TokenStream { + // 以语法树形式,构建出咱们可操作 Rust 代码的表示 + // Construct a representation of Rust code as a syntax tree + // that we can manipulate + let ast = syn::parse(input).unwrap(); + + // 构造出这个特质实现 + impl_hello_macro(&ast) +} + +fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream { + let name = &ast.ident; + let gen = quote! { + impl HelloMacro for #name { + fn hello_macro() { + println! ("你好,宏!我的名字叫 {}!", stringify! (#name)); + } + } + }; + gen.into() +} diff --git a/projects/hello_macro/src/lib.rs b/projects/hello_macro/src/lib.rs new file mode 100644 index 0000000..e747931 --- /dev/null +++ b/projects/hello_macro/src/lib.rs @@ -0,0 +1,3 @@ +pub trait HelloMacro { + fn hello_macro(); +} diff --git a/projects/hello_macro_derive/Cargo.toml b/projects/hello_macro_derive/Cargo.toml new file mode 100644 index 0000000..8fa4119 --- /dev/null +++ b/projects/hello_macro_derive/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hello_macro_derive/src/lib.rs b/projects/hello_macro_derive/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/projects/hello_macro_derive/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/projects/hello_world/Cargo.toml b/projects/hello_world/Cargo.toml new file mode 100644 index 0000000..624cb06 --- /dev/null +++ b/projects/hello_world/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hello_world" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/hello_world/src/main.rs b/projects/hello_world/src/main.rs new file mode 100644 index 0000000..96e80b1 --- /dev/null +++ b/projects/hello_world/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + // 这是注释。 + println!("Hello, World!"); +} diff --git a/projects/if_let_demo/Cargo.toml b/projects/if_let_demo/Cargo.toml new file mode 100644 index 0000000..dc397a9 --- /dev/null +++ b/projects/if_let_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "if_let_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/if_let_demo/src/main.rs b/projects/if_let_demo/src/main.rs new file mode 100644 index 0000000..af9a212 --- /dev/null +++ b/projects/if_let_demo/src/main.rs @@ -0,0 +1,22 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +fn main() { + let favorite_color: Option<&str> = None; + let is_tuesday = false; + let age: Result = "34".parse(); + + if let Some(color) = favorite_color { + println! ("使用你喜欢的颜色,{color},作为背景"); + } else if is_tuesday { + println! ("周二是绿色的一天!"); + } else if let Ok(age) = age { + if age > 30 { + println! ("使用紫色作为背景色"); + } else { + println! ("使用橙色作为背景色"); + } + } else { + println! ("使用蓝色作为背景色"); + } +} diff --git a/projects/iterator_demo/Cargo.toml b/projects/iterator_demo/Cargo.toml new file mode 100644 index 0000000..ac9fb49 --- /dev/null +++ b/projects/iterator_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "iterator_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/iterator_demo/src/lib.rs b/projects/iterator_demo/src/lib.rs new file mode 100644 index 0000000..bea2d9c --- /dev/null +++ b/projects/iterator_demo/src/lib.rs @@ -0,0 +1,35 @@ +#[derive(PartialEq, Debug)] +struct Shoe { + size: u32, + style: String, +} + +fn shoes_in_size(shoes: Vec, shoe_size: u32) -> Vec { + shoes.into_iter().filter(|s| s.size == shoe_size).collect() +} + +#[cfg(test)] +mod tests; + +#[test] +fn iterator_demonstration() { + let v1 = vec! [1, 2, 3]; + + let mut v1_iter = v1.iter(); + + assert_eq! (v1_iter.next(), Some(&1)); + assert_eq! (v1_iter.next(), Some(&2)); + assert_eq! (v1_iter.next(), Some(&3)); + assert_eq! (v1_iter.next(), None); +} + +#[test] +fn iterator_sum() { + let v1 = vec! [1, 2, 3]; + + let v1_iter = v1.iter(); + + let total: i32 = v1_iter.sum(); + + assert_eq! (total, 6); +} diff --git a/projects/iterator_demo/src/main.rs b/projects/iterator_demo/src/main.rs new file mode 100644 index 0000000..00097c5 --- /dev/null +++ b/projects/iterator_demo/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let v1 = vec! [1, 2, 3]; + + let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); + + assert_eq! (v2, vec! [2, 3, 4]); +} diff --git a/projects/iterator_demo/src/tests.rs b/projects/iterator_demo/src/tests.rs new file mode 100644 index 0000000..bbdc376 --- /dev/null +++ b/projects/iterator_demo/src/tests.rs @@ -0,0 +1,35 @@ +use super::*; + +#[test] +fn filter_by_size() { + let shoes = vec! [ + Shoe { + size: 10, + style: String::from("sneaker"), + }, + Shoe { + size: 13, + style: String::from("sandal"), + }, + Shoe { + size: 10, + style: String::from("boot"), + }, + ]; + + let in_my_size = shoes_in_size(shoes, 10); + + assert_eq! ( + in_my_size, + vec! [ + Shoe { + size: 10, + style: String::from("sneaker"), + }, + Shoe { + size: 10, + style: String::from("boot"), + }, + ] + ); +} diff --git a/projects/lifetimes_demo/Cargo.toml b/projects/lifetimes_demo/Cargo.toml new file mode 100644 index 0000000..9383aea --- /dev/null +++ b/projects/lifetimes_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "lifetimes_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/lifetimes_demo/src/main.rs b/projects/lifetimes_demo/src/main.rs new file mode 100644 index 0000000..d0bc65a --- /dev/null +++ b/projects/lifetimes_demo/src/main.rs @@ -0,0 +1,23 @@ +use std::fmt::Display; + +fn longest_with_an_announcement<'a, T>( + x: &'a str, + y: &'a str, + ann: T, +) -> &'a str +where + T: Display, +{ + println! ("通知!{}", ann); + if x.len() > y.len() { + x + } else { + y + } +} + +fn main() { + let result = longest_with_an_announcement("abc", "测试", "计算结果已出来。"); + + println! ("{}", result); +} diff --git a/projects/limit_tracker/Cargo.toml b/projects/limit_tracker/Cargo.toml new file mode 100644 index 0000000..c7089a1 --- /dev/null +++ b/projects/limit_tracker/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "limit_tracker" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/limit_tracker/src/lib.rs b/projects/limit_tracker/src/lib.rs new file mode 100644 index 0000000..27494ae --- /dev/null +++ b/projects/limit_tracker/src/lib.rs @@ -0,0 +1,77 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("出错:你已超出你的配额!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("紧急警告:你已用掉你配额的 90% !"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("警告:你已用掉你配额的 75% !"); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + sent_messages: RefCell>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: RefCell::new(vec! []), + } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + let mut borrow_one = self.sent_messages.borrow_mut(); + let mut borrow_two = self.sent_messages.borrow_mut(); + + borrow_one.push(String::from(message)); + borrow_two.push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_waring_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + println! ("{}", mock_messenger.sent_messages.borrow().iter().next().unwrap()); + + assert_eq! (mock_messenger.sent_messages.borrow().len(), 1); + } +} diff --git a/projects/loops/Cargo.toml b/projects/loops/Cargo.toml new file mode 100644 index 0000000..0d5dad5 --- /dev/null +++ b/projects/loops/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/loops/src/main.rs b/projects/loops/src/main.rs new file mode 100644 index 0000000..41b6133 --- /dev/null +++ b/projects/loops/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + for number in (1..4).rev() { + println! ("{}!", number); + } + + println! ("发射!!"); +} diff --git a/projects/lyrics_of_xmas_carol/Cargo.toml b/projects/lyrics_of_xmas_carol/Cargo.toml new file mode 100644 index 0000000..f206dd8 --- /dev/null +++ b/projects/lyrics_of_xmas_carol/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "lyrics_of_xmas_carol" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/lyrics_of_xmas_carol/src/main.rs b/projects/lyrics_of_xmas_carol/src/main.rs new file mode 100644 index 0000000..7dd9c5e --- /dev/null +++ b/projects/lyrics_of_xmas_carol/src/main.rs @@ -0,0 +1,60 @@ +fn main() { + let days = [ + "first", + "second", + "third", + "fourth", + "fifth", + "sixth", + "seventh", + "eighth", + "nineth", + "tenth", + "eleventh", + "twelfth" + ]; + let amounts = [ + "A", + "Two", + "Three", + "Four", + "Five", + "Six", + "Seven", + "Eight", + "Nine", + "Ten", + "Eleven", + "Twelve" + ]; + let things = [ + "partridge in a pear tree", + "turtle doves", + "French hens", + "calling birds", + "golden rings", + "geese-a-laying", + "swans-a-swimming", + "maids-a-milking", + "ladies dancing", + "lords-a-leaping", + "pipers piping", + "drummers drumming", + ]; + + for num in 1..=12 { + println! ("\nOn the {} day of Christmas,\nMy true love gave to me:", + days[num-1]); + for tmp in (0..num).rev() { + if tmp == 0 && num == 1 { + println! ("{} {}.", amounts[tmp], things[tmp]); + } + if tmp == 0 && num != 1 { + println! ("And {} {}.", amounts[tmp].to_lowercase(), things[tmp]); + } + if tmp != 0 { + println! ("{} {},", amounts[tmp], things[tmp]); + } + } + } +} diff --git a/projects/minigrep/Cargo.toml b/projects/minigrep/Cargo.toml new file mode 100644 index 0000000..703598f --- /dev/null +++ b/projects/minigrep/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[profile.dev] +opt-level = 1 + +[profile.release] +opt-level = 3 diff --git a/projects/minigrep/poem.txt b/projects/minigrep/poem.txt new file mode 100644 index 0000000..8707527 --- /dev/null +++ b/projects/minigrep/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/projects/minigrep/src/data_structures.rs b/projects/minigrep/src/data_structures.rs new file mode 100644 index 0000000..5d7b678 --- /dev/null +++ b/projects/minigrep/src/data_structures.rs @@ -0,0 +1,33 @@ +use std::env; + +pub struct Config { + pub query: String, + pub file_path: String, + pub ignore_case: bool, +} + +impl Config { + pub fn build( + mut args: impl Iterator, + ) -> Result { + args.next(); + + let query = match args.next() { + Some(arg) => arg, + None => return Err("未曾获取到查询字串"), + }; + + let file_path = match args.next() { + Some(arg) => arg, + None => return Err("未曾获取到文件路径"), + }; + + let ignore_case = env::var("IGNORE_CASE").is_ok(); + + Ok(Config { + query, + file_path, + ignore_case, + }) + } +} diff --git a/projects/minigrep/src/lib.rs b/projects/minigrep/src/lib.rs new file mode 100644 index 0000000..3b9fd7c --- /dev/null +++ b/projects/minigrep/src/lib.rs @@ -0,0 +1,57 @@ +#![allow(warnings)] +// +// this is to disable warnings. +// Comment it to enable warnings. +// +use std::error::Error; +use std::fs; +use data_structures::Config; +// +// 以下两种写法,也是可以的 +// +// use self::data_structures::Config; +// use crate::data_structures::Config; + +#[cfg(test)] +mod tests; +pub mod data_structures; + +pub fn run( + config: Config +) -> Result<(), Box> { + let contents = fs::read_to_string(config.file_path)?; + + let results: Vec<&str> = if config.ignore_case { + search_insensitive(&config.query, &contents) + } else { + search(&config.query, &contents) + }; + + for line in results { + println! ("{line}"); + } + + Ok(()) +} + +pub fn search<'a>( + query: &str, + contents: &'a str +) -> Vec<&'a str> { + contents + .lines() + .filter(|line| line.contains(query)) + .collect() +} + +pub fn search_insensitive<'a>( + query: &str, + contents: &'a str +) -> Vec<&'a str> { + let query = query.to_lowercase(); + + contents + .lines() + .filter(|line| line.to_lowercase().contains(&query)) + .collect() +} diff --git a/projects/minigrep/src/main.rs b/projects/minigrep/src/main.rs new file mode 100644 index 0000000..7af555f --- /dev/null +++ b/projects/minigrep/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::data_structures::Config; + +fn main() { + let config = Config::build(env::args()) + .unwrap_or_else(|err| { + eprintln! ("解析参数时遇到问题:{err}"); + process::exit(1); + }); + + println! ("在文件 {} 中检索:{}", config.file_path, config.query); + + if let Err(e) = minigrep::run(config) { + eprintln! ("应用程序错误:{e}"); + process::exit(1); + } +} diff --git a/projects/minigrep/src/tests.rs b/projects/minigrep/src/tests.rs new file mode 100644 index 0000000..5410559 --- /dev/null +++ b/projects/minigrep/src/tests.rs @@ -0,0 +1,28 @@ +use super::*; + +#[test] +fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq! (vec! ["safe, fast, productive."], search(query, contents)); +} + +#[test] +fn case_insensitive() { + let query = "rUst"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq! ( + vec! ["Rust:", "Trust me."], + search_insensitive(query, contents) + ); +} diff --git a/projects/mp_demo/Cargo.toml b/projects/mp_demo/Cargo.toml new file mode 100644 index 0000000..be7808c --- /dev/null +++ b/projects/mp_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "mp_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/mp_demo/src/main.rs b/projects/mp_demo/src/main.rs new file mode 100644 index 0000000..066d2e9 --- /dev/null +++ b/projects/mp_demo/src/main.rs @@ -0,0 +1,43 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::sync::mpsc; +use std::thread; +use std::time::Duration; + +fn main() { + let (tx, rx) = mpsc::channel(); + + let tx1 = tx.clone(); + thread::spawn(move || { + let vals = vec! [ + String::from("你好"), + String::from("自"), + String::from("此"), + String::from("线程"), + ]; + + for val in vals { + tx1.send(val).unwrap(); + thread::sleep(Duration::from_millis(500)); + } + }); + + thread::spawn(move || { + let vals = vec! [ + String::from("给"), + String::from("你"), + String::from("一些别的"), + String::from("消息"), + ]; + + for val in vals { + tx.send(val).unwrap(); + thread::sleep(Duration::from_millis(500)); + } + }); + + for received in rx { + println! ("收到:{}", received); + } +} diff --git a/projects/mutex_demo/Cargo.toml b/projects/mutex_demo/Cargo.toml new file mode 100644 index 0000000..c15b0f8 --- /dev/null +++ b/projects/mutex_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "mutex_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/mutex_demo/src/main.rs b/projects/mutex_demo/src/main.rs new file mode 100644 index 0000000..d7ac6a8 --- /dev/null +++ b/projects/mutex_demo/src/main.rs @@ -0,0 +1,27 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::sync::{Arc, Mutex}; +use std::thread; + +fn main() { + let counter = Arc::new(Mutex::new(0)); + let mut handles = vec! []; + + for _ in 0..10 { + let counter = Arc::clone(&counter); + let handle = thread::spawn(move || { + let mut num = counter.lock().unwrap(); + + *num += 1; + }); + + handles.push(handle); + } + + for handle in handles { + handle.join().unwrap(); + } + + println! ("结果为:{}", *counter.lock().unwrap()); +} diff --git a/projects/neo_simple_blog/Cargo.toml b/projects/neo_simple_blog/Cargo.toml new file mode 100644 index 0000000..501d90c --- /dev/null +++ b/projects/neo_simple_blog/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "neo_simple_blog" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/neo_simple_blog/src/lib.rs b/projects/neo_simple_blog/src/lib.rs new file mode 100644 index 0000000..38500a6 --- /dev/null +++ b/projects/neo_simple_blog/src/lib.rs @@ -0,0 +1,43 @@ +pub struct Post { + content: String, +} + +pub struct DraftPost { + content: String, +} + +impl Post { + pub fn new() -> DraftPost { + DraftPost { + content: String::new(), + } + } + + pub fn content(&self) -> &str { + &self.content + } +} + +impl DraftPost { + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn request_review(self) -> PendingReviewPost { + PendingReviewPost { + content: self.content, + } + } +} + +pub struct PendingReviewPost { + content: String, +} + +impl PendingReviewPost { + pub fn approve(self) -> Post { + Post { + content: self.content, + } + } +} diff --git a/projects/neo_simple_blog/src/main.rs b/projects/neo_simple_blog/src/main.rs new file mode 100644 index 0000000..4ab39ce --- /dev/null +++ b/projects/neo_simple_blog/src/main.rs @@ -0,0 +1,15 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use neo_simple_blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("这是一个博客帖子。"); + + let post = post.request_review(); + let post = post.approve(); + + assert_eq! ("这是一个博客帖子。", post.content()); +} diff --git a/projects/never_type/Cargo.toml b/projects/never_type/Cargo.toml new file mode 100644 index 0000000..7f1d489 --- /dev/null +++ b/projects/never_type/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "never_type" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/never_type/src/main.rs b/projects/never_type/src/main.rs new file mode 100644 index 0000000..2071f77 --- /dev/null +++ b/projects/never_type/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + print! ("永永 "); + + loop { + print! ("远远 "); + } +} diff --git a/projects/newtype/Cargo.toml b/projects/newtype/Cargo.toml new file mode 100644 index 0000000..dd63388 --- /dev/null +++ b/projects/newtype/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "newtype" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/newtype/src/main.rs b/projects/newtype/src/main.rs new file mode 100644 index 0000000..776b9d7 --- /dev/null +++ b/projects/newtype/src/main.rs @@ -0,0 +1,13 @@ +use std::fmt; + +struct Wrapper(Vec); + +impl fmt::Display for Wrapper { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write! (f, "[{}]", self.0.join(", ")) + } +} +fn main() { + let w = Wrapper(vec! [String::from("你好"), String::from("世界")]); + println! ("w = {}", w); +} diff --git a/projects/nth_fibonacci/Cargo.toml b/projects/nth_fibonacci/Cargo.toml new file mode 100644 index 0000000..633d91a --- /dev/null +++ b/projects/nth_fibonacci/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "nth_fibonacci" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num-format = "0.4.0" diff --git a/projects/nth_fibonacci/src/main.rs b/projects/nth_fibonacci/src/main.rs new file mode 100644 index 0000000..f7a6fd6 --- /dev/null +++ b/projects/nth_fibonacci/src/main.rs @@ -0,0 +1,47 @@ +use std::io; +use num_format::{Locale, ToFormattedString}; +// use std::process; + +fn nth_fibonacci(n: u64) -> u64 { + + if n == 0 || n == 1 { + return n; + } else { + return nth_fibonacci(n - 1) + nth_fibonacci(n - 2); + } +} + +fn main() { + println! ("找出第 n 个斐波拉基数"); + + 'main_loop: loop { + println! ("请输入 n: (Q/quit 退出程序)"); + + let n: u64 = loop { + let mut tmp = String::new(); + + io::stdin() + .read_line(&mut tmp) + .expect("读取输入失败!"); + + let tmp = tmp.trim(); + + if tmp.eq("Q") || tmp.eq("quit") { + // process::exit(0); + break 'main_loop; + } + + match tmp.parse() { + Ok(num) => { break num }, + Err(_) => { + println! ("请输入一个正整数!\n"); + continue; + }, + }; + }; + + println! ("第 {} 个斐波拉基数为:{}", + n, + nth_fibonacci(n).to_formatted_string(&Locale::en)); + } +} diff --git a/projects/operator_overloading/Cargo.toml b/projects/operator_overloading/Cargo.toml new file mode 100644 index 0000000..0a6eb65 --- /dev/null +++ b/projects/operator_overloading/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "operator_overloading" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/operator_overloading/src/main.rs b/projects/operator_overloading/src/main.rs new file mode 100644 index 0000000..7b7b95b --- /dev/null +++ b/projects/operator_overloading/src/main.rs @@ -0,0 +1,45 @@ +use std::ops::Add; + +#[derive(Debug, Copy, Clone, PartialEq)] +struct Point { + x: i32, + y: i32, +} + +impl Add for Point { + type Output = Point; + + fn add(self, other: Point) -> Point { + Point { + x: self.x + other.x, + y: self.y + other.y, + } + } +} + + +#[derive(Debug, Copy, Clone, PartialEq)] +struct Millimeters(u32); + +#[derive(Debug, Copy, Clone, PartialEq)] +struct Meters(u32); + +impl Add for Millimeters { + type Output = Millimeters; + + fn add(self, other: Meters) -> Millimeters { + Millimeters(self.0 + (other.0 * 1000)) + } +} + +fn main() { + assert_eq! ( + Point { x: 1, y: 0 } + Point { x: 2, y: 3}, + Point { x: 3, y: 3 } + ); + + assert_eq! ( + Millimeters(50) + Meters(1), + Millimeters(1050) + ); +} diff --git a/projects/ownership_demo/Cargo.toml b/projects/ownership_demo/Cargo.toml new file mode 100644 index 0000000..b4df443 --- /dev/null +++ b/projects/ownership_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ownership_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/ownership_demo/src/main.rs b/projects/ownership_demo/src/main.rs new file mode 100644 index 0000000..7bd91cc --- /dev/null +++ b/projects/ownership_demo/src/main.rs @@ -0,0 +1,42 @@ +fn main() { + let s = String::from("The quick brown fox jumps over the lazy dog."); + + // 函数 first_word 在 String 值的切片上有效,不管是部分还是全部的切片 + let word = first_word(&s[0..6]); + println! ("{}", word); + + let word = first_word(&s[..]); + println! ("{}", word); + + // 函数 first_word 还在 String 变量的引用上有效,而 String 变量的引用 + // 与 String 值的整个切片是等价的 + let word = first_word(&s); + println! ("{}", word); + + let s_string_literal = "hello word"; + + // 函数 first_word 在字符串字面值上有效,不论是部分还是整体 + let word = first_word(&s_string_literal[0..6]); + println! ("{}", word); + + let word = first_word(&s_string_literal[..]); + println! ("{}", word); + + // 由于字符串字面值已经 是 字符串切片,因此无需切片语法,这 + // 也是有效的! + let word = first_word(s_string_literal); + + println! ("{}", word); +} + +fn first_word(s: &str) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + + &s[..] +} diff --git a/projects/pattern_syntax_demo/Cargo.toml b/projects/pattern_syntax_demo/Cargo.toml new file mode 100644 index 0000000..240aac9 --- /dev/null +++ b/projects/pattern_syntax_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "pattern_syntax_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/pattern_syntax_demo/src/main.rs b/projects/pattern_syntax_demo/src/main.rs new file mode 100644 index 0000000..7bbf2eb --- /dev/null +++ b/projects/pattern_syntax_demo/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + enum Message { + Hello { id: u32 }, + } + + let msg = Message::Hello { id: 5 }; + + match msg { + Message::Hello { + id: id_variable @ 3..=7, + } => println! ("找到位于范围内的一个 id: {}", id_variable), + Message::Hello { id: 10..=12 } => { + println! ("找到位于另一范围的一个 {}", id); + }, + Message::Hello { id } => println! ("找到别的一个 id: {}", id), + } +} diff --git a/projects/raw_idenitifers/Cargo.toml b/projects/raw_idenitifers/Cargo.toml new file mode 100644 index 0000000..40aff17 --- /dev/null +++ b/projects/raw_idenitifers/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "raw_idenitifers" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/raw_idenitifers/src/main.rs b/projects/raw_idenitifers/src/main.rs new file mode 100644 index 0000000..61b84cf --- /dev/null +++ b/projects/raw_idenitifers/src/main.rs @@ -0,0 +1,7 @@ +fn r#match(needle: &str, haystack: &str) -> bool { + haystack.contains(needle) +} + +fn main() { + assert! (r#match("foo", "foobar")); +} diff --git a/projects/raw_pointers/Cargo.toml b/projects/raw_pointers/Cargo.toml new file mode 100644 index 0000000..e1b1b9e --- /dev/null +++ b/projects/raw_pointers/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "raw_pointers" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/raw_pointers/src/main.rs b/projects/raw_pointers/src/main.rs new file mode 100644 index 0000000..bff33b0 --- /dev/null +++ b/projects/raw_pointers/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let mut num = 5; + + let r1 = &num as *const i32; + let r2 = &mut num as *mut i32; + + unsafe { + println! ("r1 为:{}", *r1); + println! ("r2 为:{}", *r2); + } +} diff --git a/projects/rectangles/Cargo.toml b/projects/rectangles/Cargo.toml new file mode 100644 index 0000000..703c9d9 --- /dev/null +++ b/projects/rectangles/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/rectangles/src/main.rs b/projects/rectangles/src/main.rs new file mode 100644 index 0000000..a7aa76e --- /dev/null +++ b/projects/rectangles/src/main.rs @@ -0,0 +1,52 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +impl Rectangle { + fn area(&self) -> u32 { + self.width * self.height + } + + fn width(&self) -> bool { + self.width > 0 + } + + fn can_hold(&self, other: &Rectangle) -> bool { + (self.width > other.width && self.height > other.height) || + (self.width > other.height && self.height > other.width) + } + + fn square(size: u32) -> Rectangle { + Rectangle { + width: size, + height: size, + } + } +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + let rect2 = Rectangle { + width: 10, + height: 40, + }; + + let rect3 = Rectangle { + width: 45, + height: 25, + }; + + let sq1 = Rectangle::square(28); + let sq2 = Rectangle::square(35); + + println! ("rect1 可以装下 rect2 吗?{}", rect1.can_hold(&rect2)); + println! ("rect1 可以装下 rect3 吗?{}", rect1.can_hold(&rect3)); + println! ("rect1 可以装下 sq1 吗?{}", rect1.can_hold(&sq1)); + println! ("rect1 可以装下 sq2 吗?{}", rect1.can_hold(&sq2)); +} diff --git a/projects/ref_cycle_demo/Cargo.toml b/projects/ref_cycle_demo/Cargo.toml new file mode 100644 index 0000000..04d3f91 --- /dev/null +++ b/projects/ref_cycle_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ref_cycle_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/ref_cycle_demo/src/main.rs b/projects/ref_cycle_demo/src/main.rs new file mode 100644 index 0000000..6fe1657 --- /dev/null +++ b/projects/ref_cycle_demo/src/main.rs @@ -0,0 +1,42 @@ +use std::cell::RefCell; +use std::rc::Rc; +use crate::List::{Cons, Nil}; + +#[derive(Debug)] +enum List { + Cons(i32, RefCell>), + Nil, +} + +impl List { + fn tail(&self) -> Option<&RefCell>> { + match self { + Cons(_, item) => Some(item), + Nil => None, + } + } +} + +fn main() { + let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil)))); + + println! ("a 的初始 rc 计数 = {}", Rc::strong_count(&a)); + println! ("a 的下一条目 = {:?}", a.tail()); + + let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a)))); + + println! ("b 的创建后 a 的 rc 计数 = {}", Rc::strong_count(&a)); + println! ("b 的初始 rc 计数 = {}", Rc::strong_count(&b)); + println! ("b 的下一条目 = {:?}", b.tail()); + + if let Some(link) = a.tail() { + *link.borrow_mut() = Rc::clone(&b); + } + + println! ("在修改 a 之后 b 的 rc 计数 = {}", Rc::strong_count(&b)); + println! ("在修改 a 之后 a 的 rc 计数 = {}", Rc::strong_count(&a)); + + // 取消下面这行注释,就可以看到这里有着循环引用; + // 他将溢出堆栈(it will overflow the stack) + // println! ("a 的下一条目 = {:?}", a.tail()); +} diff --git a/projects/references_demo/Cargo.toml b/projects/references_demo/Cargo.toml new file mode 100644 index 0000000..e30e153 --- /dev/null +++ b/projects/references_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "references_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/references_demo/src/main.rs b/projects/references_demo/src/main.rs new file mode 100644 index 0000000..d1a400f --- /dev/null +++ b/projects/references_demo/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let mut s = String::from("你好"); + + let r1 = &s; + { + let r2 = &mut s; + r2.push_str(",世界"); + } + + println! ("s = {}, r2 = {}", s, r1); +} diff --git a/projects/refutable_demo/Cargo.toml b/projects/refutable_demo/Cargo.toml new file mode 100644 index 0000000..c3c0cb6 --- /dev/null +++ b/projects/refutable_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "refutable_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/refutable_demo/src/main.rs b/projects/refutable_demo/src/main.rs new file mode 100644 index 0000000..8b3c86b --- /dev/null +++ b/projects/refutable_demo/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + if let x = 5 { + println! ("{}", x); + } +} diff --git a/projects/restaurant/Cargo.toml b/projects/restaurant/Cargo.toml new file mode 100644 index 0000000..678b365 --- /dev/null +++ b/projects/restaurant/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/restaurant/src/front_of_house.rs b/projects/restaurant/src/front_of_house.rs new file mode 100644 index 0000000..d0a8154 --- /dev/null +++ b/projects/restaurant/src/front_of_house.rs @@ -0,0 +1 @@ +pub mod hosting; diff --git a/projects/restaurant/src/front_of_house/hosting.rs b/projects/restaurant/src/front_of_house/hosting.rs new file mode 100644 index 0000000..d65f3af --- /dev/null +++ b/projects/restaurant/src/front_of_house/hosting.rs @@ -0,0 +1 @@ +pub fn add_to_waitlist() {} diff --git a/projects/restaurant/src/lib.rs b/projects/restaurant/src/lib.rs new file mode 100644 index 0000000..639b689 --- /dev/null +++ b/projects/restaurant/src/lib.rs @@ -0,0 +1,28 @@ +mod back_of_house { + pub enum Appetizer { + Soup, + Salad, + } + + pub struct Breakfast { + pub toast: String, + seasonal_fruit: String, + } + + impl Breakfast { + pub fn summer(toast: &str) -> Breakfast { + Breakfast { + toast: String::from(toast), + seasonal_fruit: String::from("peaches"), + } + } + } +} + +mod front_of_house; + +pub use crate::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); +} diff --git a/projects/returning_closure/Cargo.toml b/projects/returning_closure/Cargo.toml new file mode 100644 index 0000000..543adda --- /dev/null +++ b/projects/returning_closure/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "returning_closure" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/returning_closure/src/main.rs b/projects/returning_closure/src/main.rs new file mode 100644 index 0000000..4b6aff7 --- /dev/null +++ b/projects/returning_closure/src/main.rs @@ -0,0 +1,7 @@ +fn returns_closure() -> Box i32> { + Box::new(|x| x + 1) +} + +fn main() { + println!("Hello, world!"); +} diff --git a/projects/rustfix_demo/Cargo.toml b/projects/rustfix_demo/Cargo.toml new file mode 100644 index 0000000..36f085f --- /dev/null +++ b/projects/rustfix_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rustfix_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/rustfix_demo/src/main.rs b/projects/rustfix_demo/src/main.rs new file mode 100644 index 0000000..e9e9e75 --- /dev/null +++ b/projects/rustfix_demo/src/main.rs @@ -0,0 +1,7 @@ +fn do_something() {} + +fn main() { + for _i in 0..100 { + do_something(); + } +} diff --git a/projects/safe_abstraction/Cargo.toml b/projects/safe_abstraction/Cargo.toml new file mode 100644 index 0000000..732d446 --- /dev/null +++ b/projects/safe_abstraction/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "safe_abstraction" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/safe_abstraction/src/main.rs b/projects/safe_abstraction/src/main.rs new file mode 100644 index 0000000..0c2f159 --- /dev/null +++ b/projects/safe_abstraction/src/main.rs @@ -0,0 +1,12 @@ +#![allow(warnings)] + +fn main() { + use std::slice; + + let address = 0x01234usize; + let r = address as *mut i32; + + let values: &[i32] = unsafe { slice::from_raw_parts_mut(r, 10000) }; + + println! ("{:?}", values); +} diff --git a/projects/simple_blog/Cargo.toml b/projects/simple_blog/Cargo.toml new file mode 100644 index 0000000..0cae12c --- /dev/null +++ b/projects/simple_blog/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "simple_blog" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/simple_blog/src/lib.rs b/projects/simple_blog/src/lib.rs new file mode 100644 index 0000000..92deec1 --- /dev/null +++ b/projects/simple_blog/src/lib.rs @@ -0,0 +1,82 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +pub struct Post { + state: Option>, + content: String, +} + +impl Post { + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn content(&self) -> &str { + self.state.as_ref().unwrap().content(self) + } + + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } + + pub fn approve(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.approve()) + } + } +} + +trait State { + fn request_review(self: Box) -> Box; + fn approve(self: Box) -> Box; + fn content<'a>(&self, post: &'a Post) -> &'a str { "" } +} + +struct Draft {} + +impl State for Draft { + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } + + fn approve(self: Box) -> Box { + self + } +} + +struct PendingReview {} + +impl State for PendingReview { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + Box::new(Published {}) + } +} + +struct Published {} + +impl State for Published { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + self + } + + fn content<'a>(&self, post: &'a Post) -> &'a str { + &post.content + } +} diff --git a/projects/simple_blog/src/main.rs b/projects/simple_blog/src/main.rs new file mode 100644 index 0000000..3503690 --- /dev/null +++ b/projects/simple_blog/src/main.rs @@ -0,0 +1,17 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use simple_blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("今天午饭我吃了沙拉。"); + assert_eq! ("", post.content()); + + post.request_review(); + assert_eq! ("", post.content()); + + post.approve(); + assert_eq! ("今天午饭我吃了沙拉。", post.content()); +} diff --git a/projects/simple_gui/Cargo.toml b/projects/simple_gui/Cargo.toml new file mode 100644 index 0000000..0de16ee --- /dev/null +++ b/projects/simple_gui/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "simple_gui" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/simple_gui/src/lib.rs b/projects/simple_gui/src/lib.rs new file mode 100644 index 0000000..f38f5b4 --- /dev/null +++ b/projects/simple_gui/src/lib.rs @@ -0,0 +1,31 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} + +pub struct Button { + pub width: u32, + pub height: u32, + pub label: String, +} + +impl Draw for Button { + fn draw(&self) { + // 具体绘制按钮的代码 + println! ("这是一个大小:{} 像素 x {} 像素,有着 “{}” 标签的按钮;", self.width, self.height, self.label); + } +} diff --git a/projects/simple_gui/src/main.rs b/projects/simple_gui/src/main.rs new file mode 100644 index 0000000..15e9d0a --- /dev/null +++ b/projects/simple_gui/src/main.rs @@ -0,0 +1,27 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use simple_gui::Draw; + +pub struct SelectBox { + width: u32, + height: u32, + options: Vec, +} + +impl Draw for SelectBox { + fn draw(&self) { + // 具体绘制复选框的代码 + println! ("这是一个大小为:{} 像素 x {} 像素,有着选项:{:?} 的复选框;", self.width, self.height, self.options); + } +} + +use simple_gui::Screen; + +pub fn main() { + let screen = Screen { + components: vec! [Box::new(String::from("你好"))], + }; + + screen.run(); +} diff --git a/projects/sp_demos/Cargo.toml b/projects/sp_demos/Cargo.toml new file mode 100644 index 0000000..e89ee27 --- /dev/null +++ b/projects/sp_demos/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "sp_demos" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/sp_demos/src/main.rs b/projects/sp_demos/src/main.rs new file mode 100644 index 0000000..8f48d41 --- /dev/null +++ b/projects/sp_demos/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let x = 5; + let y = &mut x; +} diff --git a/projects/static_variable/Cargo.toml b/projects/static_variable/Cargo.toml new file mode 100644 index 0000000..c54583c --- /dev/null +++ b/projects/static_variable/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "static_variable" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/static_variable/src/main.rs b/projects/static_variable/src/main.rs new file mode 100644 index 0000000..8b82e17 --- /dev/null +++ b/projects/static_variable/src/main.rs @@ -0,0 +1,15 @@ +static mut COUNTER: u32 = 0; + +fn add_to_count(inc: u32) { + unsafe { + COUNTER += inc; + } +} + +fn main() { + add_to_count(3); + + unsafe { + println! ("COUNTER: {}", COUNTER); + } +} diff --git a/projects/string_demo/Cargo.toml b/projects/string_demo/Cargo.toml new file mode 100644 index 0000000..1fdddff --- /dev/null +++ b/projects/string_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "string_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/string_demo/src/main.rs b/projects/string_demo/src/main.rs new file mode 100644 index 0000000..458fe32 --- /dev/null +++ b/projects/string_demo/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let s = "नमस्ते"; + + for c in s.chars() { + println!("{}", c); + } + + for b in s.bytes() { + println!("{}", b); + } +} diff --git a/projects/structs_demo/Cargo.toml b/projects/structs_demo/Cargo.toml new file mode 100644 index 0000000..fff8dd7 --- /dev/null +++ b/projects/structs_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "structs_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/supertrait/Cargo.toml b/projects/supertrait/Cargo.toml new file mode 100644 index 0000000..3d3c9a8 --- /dev/null +++ b/projects/supertrait/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "supertrait" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/supertrait/src/main.rs b/projects/supertrait/src/main.rs new file mode 100644 index 0000000..07eef4d --- /dev/null +++ b/projects/supertrait/src/main.rs @@ -0,0 +1,32 @@ +use std::fmt; + +trait OutlinePrint: fmt::Display { + fn outline_print(&self) { + let output = self.to_string(); + let len = output.len(); + + println! ("{}", "*".repeat(len + 4)); + println! ("*{}*", " ".repeat(len + 2)); + println! ("* {} *", output); + println! ("*{}*", " ".repeat(len + 2)); + println! ("{}", "*".repeat(len + 4)); + } +} + +struct Point { + x: i32, + y: i32, +} + +impl fmt::Display for Point { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write! (f, "({}, {})", self.x, self.y) + } +} + +impl OutlinePrint for Point {} + +fn main() { + let p = Point { x: -2, y: 3 }; + p.outline_print(); +} diff --git a/projects/theme/index.hbs b/projects/theme/index.hbs new file mode 100644 index 0000000..7f4abef --- /dev/null +++ b/projects/theme/index.hbs @@ -0,0 +1,319 @@ + + + + + + {{ title }} + {{#if is_print }} + + {{/if}} + {{#if base_url}} + + {{/if}} + + + + {{> head}} + + + + + + {{#if favicon_svg}} + + {{/if}} + {{#if favicon_png}} + + {{/if}} + + + + {{#if print_enable}} + + {{/if}} + + + + {{#if copy_fonts}} + + {{/if}} + + + + + + + + {{#each additional_css}} + + {{/each}} + + {{#if mathjax_support}} + + + {{/if}} + + +
+ + + + + + + + + + + + + + +
+ +
+ {{> header}} + + + + {{#if search_enabled}} + + {{/if}} + + + + +
+
+ {{{ content }}} +
+ + +
+
+ + + +
+ + {{#if live_reload_endpoint}} + + + {{/if}} + + {{#if google_analytics}} + + + {{/if}} + + {{#if playground_line_numbers}} + + {{/if}} + + {{#if playground_copyable}} + + {{/if}} + + {{#if playground_js}} + + + + + + {{/if}} + + {{#if search_js}} + + + + {{/if}} + + + + + + + {{#each additional_js}} + + {{/each}} + + {{#if is_print}} + {{#if mathjax_support}} + + {{else}} + + {{/if}} + {{/if}} + +
+ + diff --git a/projects/theme/pagetoc.css b/projects/theme/pagetoc.css new file mode 100644 index 0000000..c25e6ee --- /dev/null +++ b/projects/theme/pagetoc.css @@ -0,0 +1,62 @@ +@media only screen and (max-width:1439px) { + .sidetoc { + display: none; + } + #search-toggle { + display: none; + } +} + + +@media only screen and (min-width:1440px) { + main { + position: relative; + margin-left: calc((100% - var(--content-max-width))/2 - 120px) !important; + } + .sidetoc { + margin-left: auto; + margin-right: auto; + left: calc(100% + (var(--content-max-width))/4 - 160px); + position: absolute; + } + .pagetoc { + position: fixed; + width: 320px; + height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); + overflow: auto; + } + .pagetoc a { + border-left: 1px solid var(--sidebar-bg); + color: var(--fg) !important; + display: block; + padding-bottom: 5px; + padding-top: 5px; + padding-left: 10px; + text-align: left; + text-decoration: none; + } + .pagetoc a:hover, + .pagetoc a.active { + background: var(--sidebar-bg); + color: var(--sidebar-fg) !important; + } + .pagetoc .active { + background: var(--sidebar-bg); + color: var(--sidebar-fg); + } + .pagetoc .pagetoc-H2 { + padding-left: 20px; + } + .pagetoc .pagetoc-H3 { + padding-left: 40px; + } + .pagetoc .pagetoc-H4 { + padding-left: 60px; + } + .pagetoc .pagetoc-H5 { + display: none; + } + .pagetoc .pagetoc-H6 { + display: none; + } +} diff --git a/projects/theme/pagetoc.js b/projects/theme/pagetoc.js new file mode 100644 index 0000000..49e0bf9 --- /dev/null +++ b/projects/theme/pagetoc.js @@ -0,0 +1,49 @@ +// Un-active everything when you click it +Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el) { + el.addEventHandler("click", function() { + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el) { + el.classList.remove("active"); + }); + el.classList.add("active"); + }); +}); + +var updateFunction = function() { + + var id; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el) { + if (window.pageYOffset >= el.offsetTop) { + id = el; + } + }); + + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el) { + el.classList.remove("active"); + }); + if (!id) return; + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el) { + if (id.href.localeCompare(el.href) == 0) { + el.classList.add("active"); + } + }); +}; + +// Populate sidebar on load +window.addEventListener('load', function() { + var pagetoc = document.getElementsByClassName("pagetoc")[0]; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function (el) { + var link = document.createElement("a"); + link.appendChild(document.createTextNode(el.text)); + link.href = el.href; + link.classList.add("pagetoc-" + el.parentElement.tagName); + pagetoc.appendChild(link); + }); + updateFunction.call(); +}); + + + +// Handle active elements on scroll +window.addEventListener("scroll", updateFunction); diff --git a/projects/traits_demo/src/aggregator/lib.rs b/projects/traits_demo/src/aggregator/lib.rs new file mode 100644 index 0000000..fa644ca --- /dev/null +++ b/projects/traits_demo/src/aggregator/lib.rs @@ -0,0 +1,29 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} diff --git a/projects/tree_demo/Cargo.toml b/projects/tree_demo/Cargo.toml new file mode 100644 index 0000000..b2f4579 --- /dev/null +++ b/projects/tree_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tree_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/tree_demo/src/main.rs b/projects/tree_demo/src/main.rs new file mode 100644 index 0000000..aacc196 --- /dev/null +++ b/projects/tree_demo/src/main.rs @@ -0,0 +1,51 @@ +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +#[derive(Debug)] +struct Node { + value: i32, + parent: RefCell>, + children: RefCell>>, +} + +fn main() { + let leaf = Rc::new(Node { + value: 3, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec! []), + }); + + println! ( + "叶子节点的强引用计数:{},弱引用计数:{}\n", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + + { + let branch = Rc::new(Node { + value: 5, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec! [Rc::clone(&leaf)]), + }); + + *leaf.parent.borrow_mut() = Rc::downgrade(&branch); + + println! ( + "枝干节点的强引用计数:{},弱引用计数:{}\n", + Rc::strong_count(&branch), + Rc::weak_count(&branch), + ); + println! ( + "叶子节点的强引用计数:{},弱引用计数:{}\n", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + + } + println! ("叶子节点的父节点 = {:?}\n", leaf.parent.borrow().upgrade()); + println! ( + "叶子节点的强引用计数:{},弱引用计数:{}\n", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); +} diff --git a/projects/type_aliases/Cargo.toml b/projects/type_aliases/Cargo.toml new file mode 100644 index 0000000..7d57b28 --- /dev/null +++ b/projects/type_aliases/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "type_aliases" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/type_aliases/src/main.rs b/projects/type_aliases/src/main.rs new file mode 100644 index 0000000..0b5bb45 --- /dev/null +++ b/projects/type_aliases/src/main.rs @@ -0,0 +1,20 @@ +fn main() { + type Kilometers = i32; + + let x: i32 = 5; + let y: Kilometers = 5; + + assert_eq! (x, y); + + type Thunk = Box; + + let f: Thunk = Box::new(|| println! ("嗨")); + + fn takes_long_type(f: Thunk) { + // --跳过代码-- + } + + fn returns_long_type() -> Thunk { + // --跳过代码-- + } +} diff --git a/projects/unsafe_functions/Cargo.toml b/projects/unsafe_functions/Cargo.toml new file mode 100644 index 0000000..f5d4a5a --- /dev/null +++ b/projects/unsafe_functions/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "unsafe_functions" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/unsafe_functions/src/main.rs b/projects/unsafe_functions/src/main.rs new file mode 100644 index 0000000..92031a5 --- /dev/null +++ b/projects/unsafe_functions/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + unsafe fn dangerous() { + println! ("这是一个不安全函数。"); + } + + dangerous(); +} diff --git a/projects/unsafe_trait/Cargo.toml b/projects/unsafe_trait/Cargo.toml new file mode 100644 index 0000000..5632c0e --- /dev/null +++ b/projects/unsafe_trait/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "unsafe_trait" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/unsafe_trait/src/main.rs b/projects/unsafe_trait/src/main.rs new file mode 100644 index 0000000..53c1bb3 --- /dev/null +++ b/projects/unsafe_trait/src/main.rs @@ -0,0 +1,9 @@ +unsafe trait Foo { + // 这里是些方法 +} + +unsafe impl Foo for i32 { + // 方法实现在这里 +} + +fn main() {} diff --git a/projects/variables/Cargo.toml b/projects/variables/Cargo.toml new file mode 100644 index 0000000..f1cad76 --- /dev/null +++ b/projects/variables/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/variables/src/main.rs b/projects/variables/src/main.rs new file mode 100644 index 0000000..371f983 --- /dev/null +++ b/projects/variables/src/main.rs @@ -0,0 +1,29 @@ +use std::io; +use std::process; + +fn main() { + let a = [1, 2, 3, 4, 5]; + + println! ("请输入一个数组索引。"); + + let mut index = String::new(); + + io::stdin() + .read_line(&mut index) + .expect("读取行失败"); + + let index: usize = match index.trim() + .parse() { + Ok(num) => num, + Err(_) => { + println! ("输入的索引并非数字"); + process::exit(0); + } + }; + + let element = a[index]; + + println! ( + "位于索引 {} 处的元素值为:{}", + index, element); +} diff --git a/projects/vec_demo/Cargo.toml b/projects/vec_demo/Cargo.toml new file mode 100644 index 0000000..f7474b5 --- /dev/null +++ b/projects/vec_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "vec_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/vec_demo/src/main.rs b/projects/vec_demo/src/main.rs new file mode 100644 index 0000000..a1607b6 --- /dev/null +++ b/projects/vec_demo/src/main.rs @@ -0,0 +1,26 @@ +fn main() { + let mut v = vec! [100, 32, 57]; + + for i in &mut v { + *i += 50; + println! ("{}", i); + } + + #[derive(Debug)] + enum SpreadsheetCell { + Int(i32), + Float(f64), + Text(String), + } + + let row = vec! [ + SpreadsheetCell::Int(3), + SpreadsheetCell::Text(String::from("blue")), + SpreadsheetCell::Float(10.12), + ]; + + + println! ("{:#?}", &row[0]) + + // dbg! (v); +} diff --git a/projects/while_let_demo/Cargo.toml b/projects/while_let_demo/Cargo.toml new file mode 100644 index 0000000..c8e909e --- /dev/null +++ b/projects/while_let_demo/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "while_let_demo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/projects/while_let_demo/src/main.rs b/projects/while_let_demo/src/main.rs new file mode 100644 index 0000000..252247c --- /dev/null +++ b/projects/while_let_demo/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let (x, y) = (1, 2, 3); + + // println! ("x: {}, y: {}, z: {}", x, y, z); +} diff --git a/src/Ch21_Appendix.md b/src/Ch21_Appendix.md index f57fb51..d7c7b5e 100644 --- a/src/Ch21_Appendix.md +++ b/src/Ch21_Appendix.md @@ -688,4 +688,36 @@ Rust 每六周发布,像时刻表一样。若咱们知道了一个 Rust 发布 **Unstable Features** -这种发布模型下,还有一个好处:不稳定特性。 +这种发布模型下,还有一个好处:不稳定特性。Rust 使用了一种名为 “特性标识,feature flags” 的技巧,来确定出给定发布中启用了哪些特性。若某项新特性处于活跃开发中,他就会落地在 `master` 分支上,而由此就会在每日发布中,但会有着一个 *特性标识*。而咱们,作为用户,希望尝试这个进展中的特性,the work-in-progress feature,时,咱们是可以尝试的,但必须使用 Rust 的每日发布,并使用恰当的标识来注解咱们的代码,来选用该特性。 + +若咱们使用着 beta 或稳定发布的 Rust,那么就不能使用任何特性标识。这是 Rust 团队在声明那些新特性永久稳定前,允许咱们实际用到他们的关键。希望选用最新特性的人们,便可这样做,而想要一种扎实体验的人,则可坚持使用稳定发布,而清楚他们的代码不会破坏。这便是稳定但并非止步不前。 + +由于那些工作中的特性仍在便会,且在本书写作时和他们在稳定构建中启用时,其间他们肯定将有所不同,因此本书只包含了那些稳定特性的信息。咱们可以在线上找到那些仅每日发布有的特性文档。 + +### Rustup 与 Rust 每日发布所扮演的角色 + +**Rustup and the Role of Rust Nightly** + +Rust 令到易于在全局或每个项目基础上,从不同发布通道的 Rust 之间改变。默认情况下,咱们将安装稳定发布的 Rust。而比如要安装每日发布: + +```console +$ rustup toolchain install nightly +``` + +咱们也可以使用 `rustup`,查看全部的 *工具链,toolchains* (Rust 的各个发布与关联组件)。下面就是本书一位作者的 Windows 计算机上的示例: + +```powershell +> rustup toolchain list +stable-x86_64-pc-windows-msvc (default) +beta-x86_64-pc-windows-msvc +nightly-x86_64-pc-windows-msvc +``` + +> 在 Linux 系统上的输出如下: + +```console +$ rustup toolchain list +stable-x86_64-unknown-linux-gnu (default) +``` + +现在,当咱们每次在 `~/projects/needs-nightly` 目录下调用 `rustc` 或 `cargo` 时,`rustup` 都会确保咱们在使用每日发布的 Rust,而非咱们默认的稳定发布 Rust 了。再有很多 Rust 项目时,这就会排上用场。