• RustDay05------Exercise[41-50]


    41.使用模块的函数

    • mod 是用于创建模块的关键字。模块是一种组织代码的方式,它可以包含函数 (fn)、结构体 (struct)、枚举 (enum)、常量 (const)、其他模块 (mod) 等。
    • 模块用于组织和封装代码,帮助将代码分割成可管理的单元。模块可以形成层次结构,允许你更好地组织和管理代码。

    模块的函数一般是私有的,需要使用pub关键词将其暴露

    1. // modules1.rs
    2. // Execute `rustlings hint modules1` or use the `hint` watch subcommand for a hint.
    3. // I AM NOT DONE
    4. mod sausage_factory {
    5. // Don't let anybody outside of this module see this!
    6. fn get_secret_recipe() -> String {
    7. String::from("Ginger")
    8. }
    9. pub fn make_sausage() {
    10. get_secret_recipe();
    11. println!("sausage!");
    12. }
    13. }
    14. fn main() {
    15. sausage_factory::make_sausage();
    16. }

    42.暴露读取私有方法的函数的属性的模板变量,以选择性地公布部分属性(设置为pub)

    1. // modules2.rs
    2. // You can bring module paths into scopes and provide new names for them with the
    3. // 'use' and 'as' keywords. Fix these 'use' statements to make the code compile.
    4. // Execute `rustlings hint modules2` or use the `hint` watch subcommand for a hint.
    5. // I AM NOT DONE
    6. mod delicious_snacks {
    7. // TODO: Fix these use statements
    8. pub use self::fruits::PEAR as fruit;
    9. pub use self::veggies::CUCUMBER as veggie;
    10. mod fruits {
    11. pub const PEAR: &'static str = "Pear";
    12. pub const APPLE: &'static str = "Apple";
    13. }
    14. mod veggies {
    15. pub const CUCUMBER: &'static str = "Cucumber";
    16. pub const CARROT: &'static str = "Carrot";
    17. }
    18. }
    19. fn main() {
    20. println!(
    21. "favorite snacks: {} and {}",
    22. delicious_snacks::fruit,
    23. delicious_snacks::veggie
    24. );
    25. }

    43.导入默认库的宏和库函数

    1. // modules3.rs
    2. // You can use the 'use' keyword to bring module paths from modules from anywhere
    3. // and especially from the Rust standard library into your scope.
    4. // Bring SystemTime and UNIX_EPOCH
    5. // from the std::time module. Bonus style points if you can do it with one line!
    6. // Execute `rustlings hint modules3` or use the `hint` watch subcommand for a hint.
    7. // I AM NOT DONE
    8. // TODO: Complete this use statement
    9. use std::time::SystemTime;
    10. use std::time::UNIX_EPOCH;
    11. fn main() {
    12. match SystemTime::now().duration_since(UNIX_EPOCH) {
    13. Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
    14. Err(_) => panic!("SystemTime before UNIX EPOCH!"),
    15. }
    16. }

    44.new一个hashMap

    HashMap::new()

    注意末尾条件,添加足够种类和数量水果即可

    1. // hashmaps1.rs
    2. // A basket of fruits in the form of a hash map needs to be defined.
    3. // The key represents the name of the fruit and the value represents
    4. // how many of that particular fruit is in the basket. You have to put
    5. // at least three different types of fruits (e.g apple, banana, mango)
    6. // in the basket and the total count of all the fruits should be at
    7. // least five.
    8. //
    9. // Make me compile and pass the tests!
    10. //
    11. // Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a hint.
    12. // I AM NOT DONE
    13. use std::collections::HashMap;
    14. fn fruit_basket() -> HashMap<String, u32> {
    15. let mut basket = HashMap::new();// TODO: declare your hash map here.
    16. // Two bananas are already given for you :)
    17. basket.insert(String::from("banana"), 2);
    18. // TODO: Put more fruits in your basket here.
    19. basket.insert("666".to_string(),3);
    20. basket.insert("999".to_string(),1);
    21. basket
    22. }
    23. #[cfg(test)]
    24. mod tests {
    25. use super::*;
    26. #[test]
    27. fn at_least_three_types_of_fruits() {
    28. let basket = fruit_basket();
    29. assert!(basket.len() >= 3);
    30. }
    31. #[test]
    32. fn at_least_five_fruits() {
    33. let basket = fruit_basket();
    34. assert!(basket.values().sum::<u32>() >= 5);
    35. }
    36. }

    45.hashmap的基础插入操作

    注意末尾测试的要求即可

    1. // hashmaps2.rs
    2. // A basket of fruits in the form of a hash map is given. The key
    3. // represents the name of the fruit and the value represents how many
    4. // of that particular fruit is in the basket. You have to put *MORE
    5. // THAN 11* fruits in the basket. Three types of fruits - Apple (4),
    6. // Mango (2) and Lychee (5) are already given in the basket. You are
    7. // not allowed to insert any more of these fruits!
    8. //
    9. // Make me pass the tests!
    10. //
    11. // Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a hint.
    12. // I AM NOT DONE
    13. use std::collections::HashMap;
    14. #[derive(Hash, PartialEq, Eq)]
    15. enum Fruit {
    16. Apple,
    17. Banana,
    18. Mango,
    19. Lychee,
    20. Pineapple,
    21. }
    22. fn fruit_basket(basket: &mut HashMapu32>) {
    23. let fruit_kinds = vec![
    24. Fruit::Apple,
    25. Fruit::Banana,
    26. Fruit::Mango,
    27. Fruit::Lychee,
    28. Fruit::Pineapple,
    29. ];
    30. for fruit in fruit_kinds {
    31. // TODO: Put new fruits if not already present. Note that you
    32. // are not allowed to put any type of fruit that's already
    33. // present!
    34. }
    35. }
    36. #[cfg(test)]
    37. mod tests {
    38. use super::*;
    39. fn get_fruit_basket() -> HashMapu32> {
    40. let mut basket = HashMap::u32>::new();
    41. basket.insert(Fruit::Apple, 4);
    42. basket.insert(Fruit::Mango, 2);
    43. basket.insert(Fruit::Lychee, 5);
    44. // at_least_five_types_of_fruits 种类>=5
    45. // greater_than_eleven_fruits 总数 >=1
    46. basket.insert(Fruit::Banana, 5);
    47. basket.insert(Fruit::Pineapple, 5);
    48. basket
    49. }
    50. #[test]
    51. fn test_given_fruits_are_not_modified() {
    52. let mut basket = get_fruit_basket();
    53. fruit_basket(&mut basket);
    54. assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
    55. assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
    56. assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
    57. }
    58. #[test]
    59. fn at_least_five_types_of_fruits() {
    60. let mut basket = get_fruit_basket();
    61. fruit_basket(&mut basket);
    62. let count_fruit_kinds = basket.len();
    63. assert!(count_fruit_kinds >= 5);
    64. }
    65. #[test]
    66. fn greater_than_eleven_fruits() {
    67. let mut basket = get_fruit_basket();
    68. fruit_basket(&mut basket);
    69. let count = basket.values().sum::<u32>();
    70. assert!(count > 11);
    71. }
    72. }

    46.查看hashmap是否包含某个键

    这一题有点综合性难度了,我们需要对每场比赛的双方统计得球和失球的次数,然后通过hashMap传递出去

    1. // hashmaps3.rs
    2. // A list of scores (one per line) of a soccer match is given. Each line
    3. // is of the form :
    4. // ,,,
    5. // Example: England,France,4,2 (England scored 4 goals, France 2).
    6. // You have to build a scores table containing the name of the team, goals
    7. // the team scored, and goals the team conceded. One approach to build
    8. // the scores table is to use a Hashmap. The solution is partially
    9. // written to use a Hashmap, complete it to pass the test.
    10. // Make me pass the tests!
    11. // Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a hint.
    12. // I AM NOT DONE
    13. use std::collections::HashMap;
    14. // A structure to store team name and its goal details.
    15. struct Team {
    16. name: String,
    17. goals_scored: u8,
    18. goals_conceded: u8,
    19. }
    20. fn build_scores_table(results: String) -> HashMap<String, Team> {
    21. // The name of the team is the key and its associated struct is the value.
    22. let mut scores: HashMap<String, Team> = HashMap::new();
    23. for r in results.lines() {
    24. let v: Vec<&str> = r.split(',').collect();
    25. let team_1_name = v[0].to_string();
    26. let team_1_score: u8 = v[2].parse().unwrap();
    27. let team_2_name = v[1].to_string();
    28. let team_2_score: u8 = v[3].parse().unwrap();
    29. // TODO: Populate the scores table with details extracted from the
    30. // current line. Keep in mind that goals scored by team_1
    31. // will be number of goals conceded from team_2, and similarly
    32. // goals scored by team_2 will be the number of goals conceded by
    33. // team_1.
    34. if !scores.contains_key(&team_1_name) {
    35. // 创建新用户 都初始化为0
    36. scores.insert(team_1_name.clone(),Team{
    37. name: team_1_name.clone(),
    38. goals_scored: 0,
    39. goals_conceded: 0,
    40. });
    41. };
    42. if !scores.contains_key(&team_2_name) {
    43. // 创建新用户 都初始化为0
    44. scores.insert(team_2_name.clone(),Team{
    45. name: team_2_name.clone(),
    46. goals_scored: 0,
    47. goals_conceded: 0,
    48. });
    49. };
    50. let team1=scores.get_mut(&team_1_name).unwrap();
    51. team1.goals_scored+=team_1_score;
    52. team1.goals_conceded+=team_2_score;
    53. let team2=scores.get_mut(&team_2_name).unwrap();
    54. team2.goals_scored+=team_2_score;
    55. team2.goals_conceded+=team_1_score;
    56. }
    57. scores
    58. }
    59. #[cfg(test)]
    60. mod tests {
    61. use super::*;
    62. fn get_results() -> String {
    63. let results = "".to_string()
    64. + "England,France,4,2\n"
    65. + "France,Italy,3,1\n"
    66. + "Poland,Spain,2,0\n"
    67. + "Germany,England,2,1\n";
    68. results
    69. }
    70. #[test]
    71. fn build_scores() {
    72. let scores = build_scores_table(get_results());
    73. let mut keys: Vec<&String> = scores.keys().collect();
    74. keys.sort();
    75. assert_eq!(
    76. keys,
    77. vec!["England", "France", "Germany", "Italy", "Poland", "Spain"]
    78. );
    79. }
    80. #[test]
    81. fn validate_team_score_1() {
    82. let scores = build_scores_table(get_results());
    83. let team = scores.get("England").unwrap();
    84. assert_eq!(team.goals_scored, 5);
    85. assert_eq!(team.goals_conceded, 4);
    86. }
    87. #[test]
    88. fn validate_team_score_2() {
    89. let scores = build_scores_table(get_results());
    90. let team = scores.get("Spain").unwrap();
    91. assert_eq!(team.goals_scored, 0);
    92. assert_eq!(team.goals_conceded, 2);
    93. }
    94. }

    47.match通配和转大写/去空白字符/重复添加字符串

    对于这样的一个变量

    1. let output = transformer(vec![
    2. ("hello".into(), Command::Uppercase),
    3. (" all roads lead to rome! ".into(), Command::Trim),
    4. ("foo".into(), Command::Append(1)),
    5. ("bar".into(), Command::Append(5)),
    6. ]);

    我们需要使用如下形式来定义

    Vec<(String,Command)

    其中,枚举类型结构如下

    1. pub enum Command {
    2. Uppercase,
    3. Trim,
    4. Append(usize),
    5. }

    将字符串转大写 to_uppercase()

    output.push(string.to_uppercase())

    将字符串首尾空白字符去除

    output.push(string.trim().to_string())

    在字符串末尾重复添加特定字符串

    output.push(string.to_string()+&"bar".to_string().repeat(*nums))

    然后导入my_moduleghegmod里面的公共方法transformer到test里面去即可

    1. // quiz2.rs
    2. // This is a quiz for the following sections:
    3. // - Strings
    4. // - Vecs
    5. // - Move semantics
    6. // - Modules
    7. // - Enums
    8. // Let's build a little machine in form of a function.
    9. // As input, we're going to give a list of strings and commands. These commands
    10. // determine what action is going to be applied to the string. It can either be:
    11. // - Uppercase the string
    12. // - Trim the string
    13. // - Append "bar" to the string a specified amount of times
    14. // The exact form of this will be:
    15. // - The input is going to be a Vector of a 2-length tuple,
    16. // the first element is the string, the second one is the command.
    17. // - The output element is going to be a Vector of strings.
    18. // No hints this time!
    19. // I AM NOT DONE
    20. pub enum Command {
    21. Uppercase,
    22. Trim,
    23. Append(usize),
    24. }
    25. mod my_module {
    26. use super::Command;
    27. // TODO: Complete the function signature!
    28. pub fn transformer(input: Vec<(String,Command)>) -> Vec<String> {
    29. // TODO: Complete the output declaration!
    30. let mut output: Vec<String> = vec![];
    31. for (string, command) in input.iter() {
    32. // TODO: Complete the function body. You can do it!
    33. match command {
    34. Command::Uppercase => {
    35. output.push(string.to_uppercase())
    36. }
    37. Command::Trim => {
    38. output.push(string.trim().to_string())
    39. }
    40. Command::Append(nums) =>{
    41. output.push(string.to_string()+&"bar".to_string().repeat(*nums))
    42. }
    43. }
    44. }
    45. output
    46. }
    47. }
    48. #[cfg(test)]
    49. mod tests {
    50. // TODO: What do we have to import to have `transformer` in scope?
    51. use my_module::transformer;
    52. use super::Command;
    53. #[test]
    54. fn it_works() {
    55. let output = transformer(vec![
    56. ("hello".into(), Command::Uppercase),
    57. (" all roads lead to rome! ".into(), Command::Trim),
    58. ("foo".into(), Command::Append(1)),
    59. ("bar".into(), Command::Append(5)),
    60. ]);
    61. assert_eq!(output[0], "HELLO");
    62. assert_eq!(output[1], "all roads lead to rome!");
    63. assert_eq!(output[2], "foobar");
    64. assert_eq!(output[3], "barbarbarbarbarbar");
    65. }
    66. }

    48.根据小时来获取冰淇淋的数量

    我们首先得知道Option是一个系统默认枚举类型,其包含Some(nums)和None这两种枚举

    我们有两个任务

    (1)填补时辰和冰淇淋数量的逻辑关系并对错误的时辰进行特判

    (2)对错误的测试样例进行类型修正

    我们填写以下逻辑

    1. fn maybe_icecream(time_of_day: u16) -> Option<u16> {
    2. // We use the 24-hour system here, so 10PM is a value of 22 and 12AM is a value of 0
    3. // The Option output should gracefully handle cases where time_of_day > 23.
    4. if (time_of_day<=12) {
    5. Some(5)
    6. }
    7. else if (time_of_day<=24) {
    8. Some(0)
    9. }
    10. else{
    11. None
    12. }
    13. }

    并修改测试样 raw_value的值判断为即可

    assert_eq!(icecreams, Some(5));
    1. // options1.rs
    2. // Execute `rustlings hint options1` or use the `hint` watch subcommand for a hint.
    3. // I AM NOT DONE
    4. // This function returns how much icecream there is left in the fridge.
    5. // If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
    6. // all, so there'll be no more left :(
    7. // TODO: Return an Option!
    8. fn maybe_icecream(time_of_day: u16) -> Option<u16> {
    9. // We use the 24-hour system here, so 10PM is a value of 22 and 12AM is a value of 0
    10. // The Option output should gracefully handle cases where time_of_day > 23.
    11. if (time_of_day<=12) {
    12. Some(5)
    13. }
    14. else if (time_of_day<=24) {
    15. Some(0)
    16. }
    17. else{
    18. None
    19. }
    20. }
    21. #[cfg(test)]
    22. mod tests {
    23. use super::*;
    24. #[test]
    25. fn check_icecream() {
    26. assert_eq!(maybe_icecream(9), Some(5));
    27. assert_eq!(maybe_icecream(10), Some(5));
    28. assert_eq!(maybe_icecream(23), Some(0));
    29. assert_eq!(maybe_icecream(22), Some(0));
    30. assert_eq!(maybe_icecream(25), None);
    31. }
    32. #[test]
    33. fn raw_value() {
    34. // TODO: Fix this test. How do you get at the value contained in the Option?
    35. let icecreams = maybe_icecream(12);
    36. assert_eq!(icecreams, Some(5));
    37. }
    38. }

    48.let type(A)=unknowType(value)的使用

    这里面有两个关键语句

    let Some(word) = optional_target
    let Some(Some(integer)) = optional_integers.pop()

    他们的意思是如果等式两边类型相等,

    那么就将等式右边的值赋值给等式左边的括号里面的变量

    其可以配合if和while使用 ,也可以使用花括号对后续进行操作

    1. // options2.rs
    2. // Execute `rustlings hint options2` or use the `hint` watch subcommand for a hint.
    3. // I AM NOT DONE
    4. #[cfg(test)]
    5. mod tests {
    6. use super::*;
    7. #[test]
    8. fn simple_option() {
    9. let target = "rustlings";
    10. let optional_target = Some(target);
    11. // TODO: Make this an if let statement whose value is "Some" type
    12. if let Some(word) = optional_target {
    13. assert_eq!(word, target);
    14. }
    15. }
    16. #[test]
    17. fn layered_option() {
    18. let mut range = 10;
    19. let mut optional_integers: Vec<Option<i8>> = Vec::new();
    20. for i in 0..(range + 1) {
    21. optional_integers.push(Some(i));
    22. }
    23. // TODO: make this a while let statement - remember that vector.pop also adds another layer of Option
    24. // You can stack `Option`'s into while let and if let
    25. while let Some(Some(integer)) = optional_integers.pop() {
    26. assert_eq!(integer, range);
    27. range -= 1;
    28. }
    29. }
    30. }

    49.将引用传递给match避免产生所有权转让

    1. // options3.rs
    2. // Execute `rustlings hint options3` or use the `hint` watch subcommand for a hint.
    3. // I AM NOT DONE
    4. struct Point {
    5. x: i32,
    6. y: i32,
    7. }
    8. fn main() {
    9. let y: Option = Some(Point { x: 100, y: 200 });
    10. match &y {
    11. Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y),
    12. _ => println!("no match"),
    13. }
    14. y; // Fix without deleting this line.
    15. }

    50.错误类型处理

    处理事物错误与否,我们要使用Result枚举类型

    其包含Ok(value)和Err(value)这两种枚举

    Result代表正确时返回Ok(String),错误时返回Err(String)

    1. // errors1.rs
    2. // This function refuses to generate text to be printed on a nametag if
    3. // you pass it an empty string. It'd be nicer if it explained what the problem
    4. // was, instead of just sometimes returning `None`. Thankfully, Rust has a similar
    5. // construct to `Option` that can be used to express error conditions. Let's use it!
    6. // Execute `rustlings hint errors1` or use the `hint` watch subcommand for a hint.
    7. // I AM NOT DONE
    8. pub fn generate_nametag_text(name: String) -> Result<String,String> {
    9. if name.is_empty() {
    10. // Empty names aren't allowed.
    11. // None
    12. Err("`name` was empty; it must be nonempty.".into())
    13. } else {
    14. Ok(format!("Hi! My name is {}", name))
    15. }
    16. }
    17. #[cfg(test)]
    18. mod tests {
    19. use super::*;
    20. #[test]
    21. fn generates_nametag_text_for_a_nonempty_name() {
    22. assert_eq!(
    23. generate_nametag_text("Beyoncé".into()),
    24. Ok("Hi! My name is Beyoncé".into())
    25. );
    26. }
    27. #[test]
    28. fn explains_why_generating_nametag_text_fails() {
    29. assert_eq!(
    30. generate_nametag_text("".into()),
    31. // Don't change this line
    32. Err("`name` was empty; it must be nonempty.".into())
    33. );
    34. }
    35. }

  • 相关阅读:
    LLM大语言模型(典型ChatGPT)入门指南
    百度强推并发编程笔记我爱了,原来这才叫并发
    [Android]打开应用时导航栏闪烁问题分析
    C语言 udp通信
    UML建模案例分析-需求对类图的影响很大
    Yarn资源调度器
    回调函数(callback functions)的理解和使用
    统一潮流控制器 (UPFC) 的应用,以增强电力系统中的电压稳定性(Matlab代码实现)
    SpringCloud微服务集成Dubbo
    洛谷 P1548 [NOIP1997 普及组] 棋盘问题
  • 原文地址:https://blog.csdn.net/m0_72678953/article/details/133918054