Subtraction failed 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 message:

flag core::ops::Sub<_> not implemented for type f32

Why is this?

+5
source share
1 answer

Rust is more severe 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 operand of the right side). Rust will not automatically distinguish values โ€‹โ€‹from one primitive numeric type to another: you must insert an explicit conversion into the code. This code demonstrates the situation:

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

Unable 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 peculiarity that you mix integers and float. Rust, integer, and float literals are assigned a type based on context. So I could set a to 2 and b to 3 above: 2 not always i32 , but it is implicitly entered as i32 if this requires context.

In your case, you are trying to subtract an integer from f32 . The error message mentions Sub<_> ; that _ represents literal type 4 , which the compiler could not figure out.

The solution is to simply use floating point literals instead of whole 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<_>>(); } 
+10
source

Source: https://habr.com/ru/post/1241095/


All Articles