简体   繁体   中英

Getting mismatched types when compiling after STDIN and then math on input

I am trying to write a rust program to convert an input temperature to celcius from fahrenheit or vice versa. I am still quite new to Rust, and the book mentioned to make this program as a way to learn.

When I try to compile the code I keep getting the error mismatched types. The errors can be seen immediately below, and my code is formatted beneath the errors.

error[E0308]: mismatched types
  --> temperature.rs:12:28
   |
12 |     let temperature: u32 = temperature.trim().parse();
   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u32, found enum `std::result::Result`
   |
   = note: expected type `u32`
              found type `std::result::Result`

error[E0308]: mismatched types
  --> temperature.rs:34:29
   |
34 |         let fahr_result: f32 = ((temperature * 9) / 5) + 32;
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected f32, found u32

error[E0308]: mismatched types
  --> temperature.rs:38:29
   |
38 |         let celc_result: f32 = temperature - 32 * 5 / 9;
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^ expected f32, found u32
use std::io;

fn main () {
    println!("Welcome to the Temperature converter.");
    println!("Enter the temperature value, number only: ");

    let mut temperature = String::new();

    io::stdin().read_line(&mut temperature)
        .expect("Failed to read line");

    let temperature: u32 = temperature.trim().parse();

    println!("Do you want to convert to Celcius or Fahrenheit? (Enter the number of your choice)\n1. Fahrenheit\n2.Celcius");

    let mut temp_choice = String::new();

    io::stdin().read_line(&mut temp_choice)
        .expect("Failed to read line");

    let temp_choice: u32 = temp_choice.trim().parse()
        .expect("Fart in your butt.");

    if temp_choice == 1 {
        let fahr_result: f32 = ((temperature * 9) / 5) + 32;
        println!("{} degrees Celcius is equal to {} degrees Fahrenheit.", temperature, fahr_result);
    } else if temp_choice == 2 {
        let celc_result: f32 = temperature - 32 * 5 / 9;
        println!("{} degrees Fahrenheit is equal to {} degrees Celcius.", temperature, celc_result);
    } else {
        println!("Invalid Choice. Exiting.");
    }
}

Rust's String.parse returns a Result<F, <F as FromStr>::Err> , not a string. The simplest thing to do is to use Result.unwrap like so:

let temperature: u32 = temperature.trim().parse().unwrap();

Note that if parse returns an error result, unwrap will panic, so you may want to look at:

  • Result.unwrap_or which allows you to provide a default value on failure
  • Result.expect (as you are using elsewhere) which returns the Ok value of the result if it succeeded, or panics with the provided text argument if not

As for the other issue, this is due to the type being integer ( u32 ), and so the maths is also integer (in which, for example, 5 / 9 = 0). A simple way to get around this is:

let fahr_result: f32 = (((temperature as f32) * 9.) / 5.) + 32.;

and:

let celc_result: f32 = (temperature as f32) - 32. * 5. / 9.;

As a bonus, the celsius result calculation isn't quite right due to the order of operations, as the multiplication and division will be performed before the subtraction. You can get around this by wrapping the temperature - 32 in brackets like so:

let celc_result: f32 = ((temperature as f32) - 32.) * 5. / 9.;

I think we're both reading The Rust Programming Language and I have the same error. I solved it by:

let mut fbradley: f64 = match fbradley.trim().parse() {
    Ok(num) => num,
    Err(_) => 0.0,
};

The problem is that the output of parse is not a floating point number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM