01-类型转换

类型转换 — Rust By Example

译文 · 基于 Rust By Example

原文链接: https://doc.rust-lang.org/stable/rust-by-example/types/cast.html

类型转换

Rust 不提供原生类型之间的隐式类型转换(coercion),但可以使用 as 关键字进行显式类型转换(casting)。

整型之间的转换大体遵循 C 语言的惯例,除了 C 会产生未定义行为的情形。在 Rust 中所有整型转换都是定义良好的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 不显示类型转换产生的溢出警告。
#![allow(overflowing_literals)]

fn main() {
    let decimal = 65.4321_f32;

    // 错误!不提供隐式转换
    let integer: u8 = decimal;
    // 改正 ^ 注释掉这一行

    // 可以显式转换
    let integer = decimal as u8;
    let character = integer as char;

    println!("Casting: {} -> {} -> {}", decimal, integer, character); // Casting: 65.4321 -> 65 -> A

    // 当把任何类型转换为无符号类型 T 时,会不断加上或减去 (std::T::MAX + 1)
    // 直到值位于新类型 T 的范围内。

    // 1000 已经在 u16 的范围内
    println!("1000 as a u16 is: {}", 1000 as u16); // 1000 as a u16 is: 1000

    // 1000 - 256 - 256 - 256 = 232
    // 事实上的处理方式是:从最低有效位(LSB,least significant bits)开始保留
    // 8 位,然后剩余位置,直到最高有效位(MSB,most significant bit)都被抛弃。
    // 译注:MSB 就是二进制的最高位,LSB 就是二进制的最低位,按日常书写习惯就是
    // 最左边一位和最右边一位。
    println!("1000 as a u8 is : {}", 1000 as u8); // 1000 as a u8 is : 232
    // -1 + 256 = 255
    println!("  -1 as a u8 is : {}", (-1i8) as u8); //   -1 as a u8 is : 255

    // 对正数,这就和取模一样。
    println!("1000 mod 256 is : {}", 1000 % 256); // 1000 mod 256 is : 232

    // 当转换到有符号类型时,(位操作的)结果就和 “先转换到对应的无符号类型,
    // 如果 MSB 是 1,则该值为负” 是一样的。

    // 当然如果数值已经在目标类型的范围内,就直接把它放进去。
    println!(" 128 as a i16 is: {}", 128 as i16); //  128 as a i16 is: 128
    // 128 转成 u8 还是 128,但转到 i8 相当于给 128 取八位的二进制补码,其值是:
    println!(" 128 as a i8 is : {}", 128 as i8); //  128 as a i8 is : -128

    // 重复之前的例子
    // 1000 as u8 -> 232
    println!("1000 as a u8 is : {}", 1000 as u8); // 1000 as a u8 is : 232
    // 232 的二进制补码是 -24
    println!(" 232 as a i8 is : {}", 232 as i8); //  232 as a i8 is : -24
}
最后修改 October 2, 2026: 更新 (f3447ada6)