How do I convert a boolean to an integer in Rust? As in, true becomes 1, and false becomes 0.
4 Answers
Cast it:
fn main() { println!("{}", true as i32) } 4 Comments
Chris Vilches
Works, but this is too C++. Even Java would complain about this, and Rust should too, in my opinion.
Newbyte
@ChrisVilches why?
Chris Vilches
@Newbyte A
true is a 1 only from a hardware point of view (and we can only assume non-exotic hardware), but not from a conceptual point of view. Which is fine, since it's a valid way to model it. In Java, 1 and true are two different concepts.Newbyte
@ChrisVilches a bool having a value other than 0 or 1 is considered undefined behaviour: doc.rust-lang.org/reference/behavior-considered-undefined.html
A boolean value in Rust is guaranteed to be 1 or 0:
The
boolrepresents a value, which could only be eithertrueorfalse. If you cast aboolinto an integer,truewill be 1 andfalsewill be 0.
A boolean value, which is neither 0 nor 1 is undefined behavior:
A value other than
false(0) ortrue(1) in a bool.
Therefore, you can just cast it to a primitive:
assert_eq!(0, false as i32); assert_eq!(1, true as i32); Comments
Use an if statement:
if some_boolean { 1 } else { 0 } See also:
6 Comments
Stein
A simple benchmark shows that this is 20% faster than the other answers.
Tim Diekmann
@Stein I think your link is outdated.
Solomon Ucko
@Stein Current nightly appears to generate identical code for
is_some_as and is_some_if: rust.godbolt.org/z/edcKef.Stein
@SolomonUcko Not quite, it seems. The benchmarks still report the same difference today (regardless of names and place in file, which could influence alignment). When I swap the
-O in your very useful godbolt link with the -C opt-level=3 that cargo bench feeds, it does report a difference in assembly.Stein
Rust issue #95522 (possibly an LLVM issue) suggests this is not the best way to write it, in the rare case performance matters extremely. Contrary to that, the option_cardinality part of a simple microbenchmark suggests it is faster, with most Rust builds, but I believe that benchmark misrepresents bool-to-integer conversion because it basically checks
if pointer != null { 1 } else { 0 }, which should branch anyway. |
You may use .into():
let a = true; let b: i32 = a.into(); println!("{}", b); // 1 let z: isize = false.into(); println!("{}", z); // 0 1 Comment
Chayim Friedman
Or
from: i32::from(b).
trueandfalse.pub fn calculateprice(num : i32) -> i32 { return ((num > 40) as i32 * num) + num; }