How to idiomatically convert between u32 and usize?

后端 未结 3 1550
隐瞒了意图╮
隐瞒了意图╮ 2020-12-06 16:29

This code works and prints \"b\":

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

On t

相关标签:
3条回答
  • 2020-12-06 16:49

    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.

    0 讨论(0)
  • 2020-12-06 16:54

    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
    }
    
    0 讨论(0)
  • 2020-12-06 16:57

    We now have a pretty different answer when we try to compile your code, replacing the number 1 with a variable of type i32:

    error[E0308]: mismatched types
     --> src/main.rs:5:28
      |
    5 |     let ch = s.chars().nth(n).unwrap();
      |                            ^ expected usize, found i32
    help: you can convert an `i32` to `usize` and panic if the converted value wouldn't fit
      |
    5 |     let ch = s.chars().nth(n.try_into().unwrap()).unwrap();
      |    
    

    It means that now the compiler recommends you to use n.try_into().unwrap() that makes use of the trait TryInto which in turn relies on TryFrom and returns a Result<T, T::Error>. That's why we need to extract the result with a .unwrap()

    TryInto documentation

    0 讨论(0)
提交回复
热议问题