简体   繁体   中英

Subtraction not implemented for f32?

When compiling the following code:

use std::io::*;

fn main(){
    let reader = stdin();
    let nums = reader.lock()
        .lines().next().unwrap().unwrap()
        .split_whitespace()
        .map(|s| s.parse::<i32>().unwrap())
        .map(|s| s as f32)
        .map(|s| (s - 4) / 2)
        .map(|s| s as i32)
        .collect();
}

I get an error saying:

the trait core::ops::Sub<_> is not implemented for the type f32

Why is this?

Rust is stricter than some other languages when it comes to manipulating primitive types. Most math operators require the same type on both sides (with the exception of bit shifts, which expect a usize as the right-hand side operand). Rust will not automatically cast values from one primitive numeric type to another: you must insert an explicit cast in the code. This code demonstrates the situation:

fn main(){
    let a: i32 = 2;
    let b: i8 = 3;
    println!("{}", a + b);
}

It fails to compile with the following errors:

<anon>:4:24: 4:25 error: mismatched types:
 expected `i32`,
    found `i8`
(expected i32,
    found i8) [E0308]
<anon>:4     println!("{}", a + b);
                                ^
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
<anon>:4:5: 4:27 note: in this expansion of println! (defined in <std macros>)
<anon>:4:24: 4:25 help: see the detailed explanation for E0308
<anon>:4:20: 4:25 error: the trait `core::ops::Add<i8>` is not implemented for the type `i32` [E0277]
<anon>:4     println!("{}", a + b);
                            ^~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
<anon>:4:5: 4:27 note: in this expansion of println! (defined in <std macros>)
<anon>:4:20: 4:25 help: see the detailed explanation for E0277

Your situation is similar, but it has the particularity that you're mixing integers and floats. In Rust, integer and float literals are assigned a type based on context. That's why I could set a to 2 and b to 3 above: 2 is not always an i32 , but it is implicitly typed as i32 if the context requires it.

In your case, you're trying to subtract an integer from an f32 . The error message mentions Sub<_> ; that _ represents the type of the 4 literal that the compiler wasn't able to figure out.

The solution is simply to use float literals instead of integer literals:

use std::io::*;

fn main(){
    let reader = stdin();
    let nums = reader.lock()
        .lines().next().unwrap().unwrap()
        .split_whitespace()
        .map(|s| s.parse::<i32>().unwrap())
        .map(|s| s as f32)
        .map(|s| (s - 4.0) / 2.0)
        .map(|s| s as i32)
        .collect::<Vec<_>>();
}

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