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 typef32
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<_>>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With