Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to idiomatically convert between u32 and usize?

This code works and prints "b":

fn main() {     let s = "abc";     let ch = s.chars().nth(1).unwrap();     println!("{}", ch); } 

On the other hand, this code results in a mismatch type error.

fn main() {     let s = "abc";     let n: u32 = 1;     let ch = s.chars().nth(n).unwrap();     println!("{}", ch); } 
error[E0308]: mismatched types  --> src/main.rs:5:28   | 5 |     let ch = s.chars().nth(n).unwrap();   |                            ^ expected usize, found u32 

For some external reason, I have to use the u32 type for variable n. How can I convert u32 to usize and use it in nth()?

like image 261
Sajuuk Avatar asked Apr 30 '17 09:04

Sajuuk


2 Answers

The most cautious thing you can do is to use TryFrom and panic when the value cannot fit within a usize:

use std::convert::TryFrom;  fn main() {     let s = "abc";     let n: u32 = 1;     let n_us = usize::try_from(n).unwrap();     let ch = s.chars().nth(n_us).unwrap();     println!("{}", ch); } 

By blindly using as, your code will fail in mysterious ways when run on a platform where usize is smaller than 32-bits. For example, some microcontrollers use 16-bit integers as the native size:

fn main() {     let n: u32 = 0x1_FF_FF;     // Pretend that `usize` is 16-bit     let n_us: u16 = n as u16;          println!("{}, {}", n, n_us); // 131071, 65535 } 

For broader types of numeric conversion beyond u32 <-> usize, refer to How do I convert between numeric types safely and idiomatically?.

See also:

  • Why is type conversion from u64 to usize allowed using `as` but not `From`?
like image 37
Shepmaster Avatar answered Sep 26 '22 03:09

Shepmaster


The as operator works for all number types:

let ch = s.chars().nth(n as usize).unwrap(); 

Rust forces you to cast integers to make sure you're aware of signedness or overflows.

Integer constants can have a type suffix:

let n = 1u32; 

However, note that negative constants, such as -1i32 is internally - 1i32.

Integer variables declared without an explicit type specification are shown as {integer} and will be properly inferred from one of the method calls.

like image 118
Tatsuyuki Ishi Avatar answered Sep 23 '22 03:09

Tatsuyuki Ishi