Skip to content
On this page

if3: exercises/if/if3.rs

题目

rust
// if3.rs
//
// Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint.

// I AM NOT DONE

pub fn animal_habitat(animal: &str) -> &'static str {
    let identifier = if animal == "crab" {
        1
    } else if animal == "gopher" {
        2.0
    } else if animal == "snake" {
        3
    } else {
        "Unknown"
    };

    // DO NOT CHANGE THIS STATEMENT BELOW
    let habitat = if identifier == 1 {
        "Beach"
    } else if identifier == 2 {
        "Burrow"
    } else if identifier == 3 {
        "Desert"
    } else {
        "Unknown"
    };

    habitat
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn gopher_lives_in_burrow() {
        assert_eq!(animal_habitat("gopher"), "Burrow")
    }

    #[test]
    fn snake_lives_in_desert() {
        assert_eq!(animal_habitat("snake"), "Desert")
    }

    #[test]
    fn crab_lives_on_beach() {
        assert_eq!(animal_habitat("crab"), "Beach")
    }

    #[test]
    fn unknown_animal() {
        assert_eq!(animal_habitat("dinosaur"), "Unknown")
    }
}

题目解析

根据单元测试内容,我们分析出函数fn animal_habitat(animal: &str) -> &'static str大致功能为:

  • 当传递gopher返回Burrow
  • 当传递snake返回Desert
  • 当传递crab返回Beach
  • 当传递dinosaur返回Unknown

再来看函数animal_habitat的逻辑,首先是变量identifier的赋值逻辑:

rust
let identifier = if animal == "crab" {
        1
    } else if animal == "gopher" {
        2.0
    } else if animal == "snake" {
        3
    } else {
        "Unknown"
    };
  • animal == "crab"时候,identifier = 1
  • animal == "gopher"时候,identifier = 2.0
  • animal == "snake"时候,identifier = 3
  • 其他情况,identifier = Unknown

我们根据上一个题目里面的知识,条件语句的每个匹配项返回值应该是一样的才对,这里有返回整型,也有返回浮点型,也有返回&str类型,肯定是不对的。

我们可以在编译器错误信息里得到验证:

txt
⚠️  Compiling of exercises/if/if3.rs failed! Please try again. Here's the output:
error[E0308]: `if` and `else` have incompatible types
  --> exercises/if/if3.rs:15:9
   |
12 |       } else if animal == "snake" {
   |  ____________-
13 | |         3
   | |         - expected because of this
14 | |     } else {
15 | |         "Unknown"
   | |         ^^^^^^^^^ expected integer, found `&str`
16 | |     };
   | |_____- `if` and `else` have incompatible types

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

我们根据后面返回值的逻辑:

rust
// DO NOT CHANGE THIS STATEMENT BELOW
    let habitat = if identifier == 1 {
        "Beach"
    } else if identifier == 2 {
        "Burrow"
    } else if identifier == 3 {
        "Desert"
    } else {
        "Unknown"
    };

    habitat
  • 函数最终是返回habitat
  • identifier == 1返回Beach
  • identifier == 2返回Burrow
  • identifier == 3返回Desert
  • 其他的都返回Unknown

所以我们可以把identifier赋值全部改成i32类型的:

rust
pub fn animal_habitat(animal: &str) -> &'static str {
    let identifier = if animal == "crab" {
        1
    } else if animal == "gopher" { 
        2.0 
    } else if animal == "snake" { 
        3 
    } else { 
        "Unknown" 
    }; 
    } else if animal == "gopher" { 
        2 
    } else if animal == "snake" { 
        3 
    } else { 
        4 
    }; 

    // DO NOT CHANGE THIS STATEMENT BELOW
    let habitat = if identifier == 1 {
        "Beach"
    } else if identifier == 2 {
        "Burrow"
    } else if identifier == 3 {
        "Desert"
    } else {
        "Unknown"
    };

    habitat
}

笔记

  • 在rust中,条件语句的每个条件块应该返回相同的类型

参考资料

Powered by VitePress