Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I compare two integers of different types?

let x: i32 = 4;
let y: i16 = 4;

println!("{}", x == y);

When compiling the snippet above, the compiler prints the following error:

error[E0308]: mismatched types
 --> src/main.rs:5:25
  |
5 |     println!("{}", x == y);
  |                         ^ expected i32, found i16

It seems that PartialEq is not implemented for different types of integers. The same happens between f32 and f64, and for PartialOrd as well. Is there a reason for that? Is it intended to be implemented in future versions of Rust?

like image 833
Milack27 Avatar asked Jan 12 '18 11:01

Milack27


People also ask

How do you compare two integer values?

Syntax : public static int compare(int x, int y) Parameter : x : the first int to compare y : the second int to compare Return : This method returns the value zero if (x==y), if (x < y) then it returns a value less than zero and if (x > y) then it returns a value greater than zero.

How do you compare two integers equal in Java?

To check two numbers for equality in Java, we can use the Equals() method as well as the == operator. Firstly, let us set Integers. Integer val1 = new Integer(5); Integer val2 = new Integer(5); Now, to check whether they are equal or not, let us use the == operator.

Which special character is used to compare two numbers?

→ Equals to sign can be used to compare two integers.


2 Answers

It is expected behaviour - Rust is a strongly typed language and it doesn't perform implicit casts between integers of different types.

I don't think this will ever change in the future, as it would be a potential source of bugs that are notoriously difficult to find.

You need to be explicit and watch out for potential caveats of numeric casts (truncation etc.):

let x: i32 = 4;
let y: i16 = 4;

println!("{}", x == y as i32);
like image 88
ljedrz Avatar answered Nov 23 '22 11:11

ljedrz


There are many integral types, in Rust:

  • i8, i16, i32, i64 and i128,
  • u8, u16, u32, u64 and u128,
  • isize,
  • usize.

In some cases, mixed arithmetic or comparisons would have an obvious implementation as a lossless conversion is possible in one direction:

  • i<x> can always be converted to i<y> if x < y,
  • u<x> can always be converted to u<y> if x < y,
  • u<x> can always be converted to i<y> if x < y.

Some conversions, however, are not obvious or not portable:

  • i<x> cannot be converted to u<y> no matter what the respective values of x and y are,
  • isize and usize have a platform specific size anywhere, as small as 16 bits but as large as 64 bits.

Therefore, since Rust is not keen on overflows or underflows, it is unlikely that arbitrary mixed arithmetic or comparisons will ever be implemented.

A restricted subset could be implemented, but then two questions are raised:

  • isn't a restricted subset unergonomic?
  • isn't using mixed types a sign of design issue? In the same vein that quantities should have units, quantities should probably have a known magnitude.
like image 21
Matthieu M. Avatar answered Nov 23 '22 11:11

Matthieu M.