Rust 类型转换:显式类型转换

RustRustBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个实验中,我们将学习 Rust 中的类型转换,以及如何使用 as 关键字进行显式类型转换。

注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 main.rs,并通过 rustc main.rs &&./main 进行编译和运行。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/unsafe_rust("Unsafe Rust") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/integer_types -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/floating_types -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/type_casting -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/function_syntax -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/expressions_statements -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/lifetime_specifiers -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/unsafe_rust -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} rust/operator_overloading -.-> lab-99295{{"Rust 类型转换:显式类型转换"}} end

类型转换

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

整数类型之间的转换规则通常遵循 C 语言的约定,但在 C 语言存在未定义行为的情况下除外。在 Rust 中,所有整数类型之间的转换行为都是明确定义的。

// 抑制所有因类型转换溢出而产生的警告。
#![allow(overflowing_literals)]

fn main() {
    let decimal = 65.4321_f32;

    // 错误!不存在隐式转换
    let integer: u8 = decimal;
    // FIXME ^ 注释掉这一行

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

    // 错误!转换规则存在限制。
    // 浮点数不能直接转换为字符。
    let character = decimal as char;
    // FIXME ^ 注释掉这一行

    println!("类型转换: {} -> {} -> {}", decimal, integer, character);

    // 当将任何值转换为无符号类型 T 时,
    // 会加上或减去 T::MAX + 1,直到该值适合新类型

    // 1000 已经适合 u16 类型
    println!("1000 作为 u16 是: {}", 1000 as u16);

    // 1000 - 256 - 256 - 256 = 232
    // 在底层,保留最低有效位的前 8 位,
    // 而向最高有效位的其余位则被截断。
    println!("1000 作为 u8 是 : {}", 1000 as u8);
    // -1 + 256 = 255
    println!("  -1 作为 u8 是 : {}", (-1i8) as u8);

    // 对于正数,这与取模运算相同
    println!("1000 对 256 取模是 : {}", 1000 % 256);

    // 当转换为有符号类型时,(按位)结果与
    // 先转换为相应的无符号类型相同。如果该值的最高有效位为 1,那么该值为负数。

    // 当然,除非它已经适合。
    println!(" 128 作为 i16 是: {}", 128 as i16);

    // 在边界情况下,8 位二进制补码表示中的 128 值是 -128
    println!(" 128 作为 i8 是 : {}", 128 as i8);

    // 重复上面的示例
    // 1000 作为 u8 -> 232
    println!("1000 作为 u8 是 : {}", 1000 as u8);
    // 8 位二进制补码表示中 232 的值是 -24
    println!(" 232 作为 i8 是 : {}", 232 as i8);

    // 自 Rust 1.45 起,`as` 关键字在从浮点数转换为整数时执行 *饱和转换*。
    // 如果浮点值超过上限或小于下限,返回的值
    // 将等于越过的边界值。

    // 300.0 作为 u8 是 255
    println!(" 300.0 作为 u8 是 : {}", 300.0_f32 as u8);
    // -100.0 作为 u8 是 0
    println!("-100.0 作为 u8 是 : {}", -100.0_f32 as u8);
    // nan 作为 u8 是 0
    println!("   nan 作为 u8 是 : {}", f32::NAN as u8);

    // 这种行为会带来少量的运行时开销,可以通过不安全方法避免,
    // 但是结果可能会溢出并返回 **无效值**。请谨慎使用这些方法:
    unsafe {
        // 300.0 作为 u8 是 44
        println!(" 300.0 作为 u8 是 : {}", 300.0_f32.to_int_unchecked::<u8>());
        // -100.0 作为 u8 是 156
        println!("-100.0 作为 u8 是 : {}", (-100.0_f32).to_int_unchecked::<u8>());
        // nan 作为 u8 是 0
        println!("   nan 作为 u8 是 : {}", f32::NAN.to_int_unchecked::<u8>());
    }
}

总结

恭喜你!你已经完成了类型转换实验。你可以在 LabEx 中练习更多实验来提升你的技能。