Propriété et Mouvements

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, il est expliqué que dans Rust, les variables ont la propriété des ressources et ne peuvent avoir qu'un seul propriétaire, ce qui empêche les ressources d'être libérées plusieurs fois. Lorsque des variables sont assignées ou que des arguments de fonction sont passés par valeur, la propriété des ressources est transférée, ce qui est appelé un move. Après le move, l'ancien propriétaire ne peut plus être utilisé pour éviter de créer des pointeurs faussaires. L'exemple de code illustre ces concepts en montrant comment la propriété des variables allouées sur la pile et sur le tas est transférée et comment accéder à une variable après que sa propriété a été transférée entraîne des erreurs.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. 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/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer 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/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99195{{"Propriété et Mouvements"}} rust/integer_types -.-> lab-99195{{"Propriété et Mouvements"}} rust/type_casting -.-> lab-99195{{"Propriété et Mouvements"}} rust/function_syntax -.-> lab-99195{{"Propriété et Mouvements"}} rust/expressions_statements -.-> lab-99195{{"Propriété et Mouvements"}} rust/lifetime_specifiers -.-> lab-99195{{"Propriété et Mouvements"}} rust/method_syntax -.-> lab-99195{{"Propriété et Mouvements"}} rust/operator_overloading -.-> lab-99195{{"Propriété et Mouvements"}} end

Propriété et mouvements

Étant donné que les variables sont chargées de libérer leurs propres ressources, une ressource ne peut avoir qu'un seul propriétaire. Cela empêche également les ressources d'être libérées plus d'une fois. Notez que non toutes les variables possèdent des ressources (par exemple, les [références]).

Lorsque l'on effectue des affectations (let x = y) ou que l'on passe des arguments de fonction par valeur (foo(x)), la propriété des ressources est transférée. En langage Rust, on appelle cela un move.

Après avoir transféré les ressources, l'ancien propriétaire ne peut plus être utilisé. Cela évite de créer des pointeurs faussaires.

// Cette fonction prend la propriété de la mémoire allouée sur le tas
fn destroy_box(c: Box<i32>) {
    println!("Destroying a box that contains {}", c);

    // `c` est détruit et la mémoire est libérée
}

fn main() {
    // Entier alloué sur la _pile_
    let x = 5u32;

    // *Copie* `x` dans `y` - aucune ressource n'est déplacée
    let y = x;

    // Les deux valeurs peuvent être utilisées indépendamment
    println!("x is {}, and y is {}", x, y);

    // `a` est un pointeur vers un entier alloué sur le _tas_
    let a = Box::new(5i32);

    println!("a contains: {}", a);

    // *Déplace* `a` dans `b`
    let b = a;
    // L'adresse du pointeur de `a` est copiée (pas les données) dans `b`.
    // Les deux sont maintenant des pointeurs vers les mêmes données allouées sur le tas, mais
    // `b` en est maintenant le propriétaire.

    // Erreur! `a` ne peut plus accéder aux données, car il ne possède plus
    // la mémoire du tas
    //println!("a contains: {}", a);
    // TODO ^ Essayez de décommenter cette ligne

    // Cette fonction prend la propriété de la mémoire allouée sur le tas à partir de `b`
    destroy_box(b);

    // Étant donné que la mémoire du tas a été libérée à ce stade, cette action entraînerait
    // une déréférencement de mémoire libérée, mais le compilateur l'interdit
    // Erreur! Même raison que l'erreur précédente
    //println!("b contains: {}", b);
    // TODO ^ Essayez de décommenter cette ligne
}

Sommaire

Félicitations ! Vous avez terminé le laboratoire sur la Propriété et les Mouvements. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.