Typage explicite en Rust : Conversion de type explicite

RustRustBeginner
Pratiquer maintenant

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

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous allons apprendre le typage explicite en Rust et comment effectuer une conversion de type explicite en utilisant le mot clé as.

Note : Si le nom de fichier n'est pas spécifié dans le laboratoire, vous pouvez utiliser n'importe quel nom de fichier. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) 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{{"Typage explicite en Rust : Conversion de type explicite"}} rust/integer_types -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/floating_types -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/type_casting -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/function_syntax -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/expressions_statements -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/lifetime_specifiers -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/unsafe_rust -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} rust/operator_overloading -.-> lab-99295{{"Typage explicite en Rust : Conversion de type explicite"}} end

Typage explicite

Rust ne fournit pas de conversion implicite de type (coercition) entre les types primitifs. Cependant, une conversion de type explicite (typage) peut être effectuée en utilisant le mot clé as.

Les règles de conversion entre les types entiers suivent généralement les conventions C, sauf dans les cas où C présente un comportement indéfini. Le comportement de tous les typages entre les types entiers est bien défini en Rust.

// Supprime tous les avertissements provenant de typages qui entraînent un dépassement de capacité.
#![allow(overflowing_literals)]

fn main() {
    let decimal = 65.4321_f32;

    // Erreur! Aucune conversion implicite
    let integer: u8 = decimal;
    // FIXME ^ Commenter cette ligne

    // Conversion explicite
    let integer = decimal as u8;
    let character = integer as char;

    // Erreur! Il y a des limites dans les règles de conversion.
    // Un nombre à virgule flottante ne peut pas être directement converti en un caractère.
    let character = decimal as char;
    // FIXME ^ Commenter cette ligne

    println!("Typage : {} -> {} -> {}", decimal, integer, character);

    // Lors du typage de n'importe quelle valeur en un type non signé, T,
    // T::MAX + 1 est ajouté ou soustrait jusqu'à ce que la valeur
    // rentre dans le nouveau type

    // 1000 rentre déjà dans un u16
    println!("1000 en tant que u16 est : {}", 1000 as u16);

    // 1000 - 256 - 256 - 256 = 232
    // Sous le capot, les 8 premiers bits les moins significatifs (LSB) sont conservés,
    // tandis que le reste vers le bit le plus significatif (MSB) est tronqué.
    println!("1000 en tant que u8 est : {}", 1000 as u8);
    // -1 + 256 = 255
    println!("  -1 en tant que u8 est : {}", (-1i8) as u8);

    // Pour les nombres positifs, c'est la même chose que le modulo
    println!("1000 modulo 256 est : {}", 1000 % 256);

    // Lors du typage en un type signé, le résultat (au niveau du bit) est le même que
    // d'abord typage en le type non signé correspondant. Si le bit le plus significatif
    // de cette valeur est 1, alors la valeur est négative.

    // Sauf bien sûr si elle rentre déjà.
    println!(" 128 en tant que i16 est : {}", 128 as i16);

    // Dans le cas limite, la valeur 128 en représentation à complément à deux sur 8 bits est -128
    println!(" 128 en tant que i8 est : {}", 128 as i8);

    // Répétition de l'exemple ci-dessus
    // 1000 en tant que u8 -> 232
    println!("1000 en tant que u8 est : {}", 1000 as u8);
    // et la valeur de 232 en représentation à complément à deux sur 8 bits est -24
    println!(" 232 en tant que i8 est : {}", 232 as i8);

    // Depuis Rust 1.45, le mot clé `as` effectue un *typage saturant*
    // lors du typage d'un nombre à virgule flottante en un entier. Si la valeur flottante dépasse
    // la borne supérieure ou est inférieure à la borne inférieure, la valeur renvoyée
    // sera égale à la borne dépassée.

    // 300.0 en tant que u8 est 255
    println!(" 300.0 en tant que u8 est : {}", 300.0_f32 as u8);
    // -100.0 en tant que u8 est 0
    println!("-100.0 en tant que u8 est : {}", -100.0_f32 as u8);
    // nan en tant que u8 est 0
    println!("   nan en tant que u8 est : {}", f32::NAN as u8);

    // Ce comportement entraîne un coût de runtime légèrement plus élevé et peut être évité
    // avec des méthodes non sûres, cependant les résultats peuvent déborder et
    // renvoyer des **valeurs non valides**. Utilisez ces méthodes avec prudence :
    unsafe {
        // 300.0 en tant que u8 est 44
        println!(" 300.0 en tant que u8 est : {}", 300.0_f32.to_int_unchecked::<u8>());
        // -100.0 en tant que u8 est 156
        println!("-100.0 en tant que u8 est : {}", (-100.0_f32).to_int_unchecked::<u8>());
        // nan en tant que u8 est 0
        println!("   nan en tant que u8 est : {}", f32::NAN.to_int_unchecked::<u8>());
    }
}

Résumé

Félicitations! Vous avez terminé le laboratoire sur le typage explicite. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.