Rouille - Propriété

La mémoire d'un programme peut être allouée de la manière suivante -

  • Stack
  • Heap

Empiler

Une pile suit un dernier dans le premier ordre sorti. Stack stocke les valeurs de données dont la taille est connue au moment de la compilation. Par exemple, une variable de taille fixe i32 est candidate à l'allocation de pile. Sa taille est connue au moment de la compilation. Tous les types scalaires peuvent être stockés dans la pile car la taille est fixe.

Prenons un exemple de chaîne à laquelle une valeur est affectée au moment de l'exécution. La taille exacte d'une telle chaîne ne peut pas être déterminée au moment de la compilation. Ce n'est donc pas un candidat pour l'allocation de pile mais pour l'allocation de tas.

Tas

La mémoire du tas stocke des valeurs de données dont la taille est inconnue au moment de la compilation. Il est utilisé pour stocker des données dynamiques. En termes simples, une mémoire de tas est allouée à des valeurs de données qui peuvent changer tout au long du cycle de vie du programme. Le tas est une zone de la mémoire qui est moins organisée que la pile.

Qu'est-ce que la propriété?

Chaque valeur de Rust a une variable appelée ownerde la valeur. Chaque donnée stockée dans Rust sera associée à un propriétaire. Par exemple, dans la syntaxe - let age = 30, age est le propriétaire de la valeur 30 .

  • Chaque donnée ne peut avoir qu'un seul propriétaire à la fois.

  • Deux variables ne peuvent pas pointer vers le même emplacement mémoire. Les variables pointeront toujours vers différents emplacements de mémoire.

Transfert de propriété

La propriété de la valeur peut être transférée par -

  • Attribution de la valeur d'une variable à une autre variable.

  • Passer de la valeur à une fonction.

  • Valeur renvoyée par une fonction.

Attribution de la valeur d'une variable à une autre variable

Le principal argument de vente de Rust en tant que langue est la sécurité de sa mémoire. La sécurité de la mémoire est assurée par un contrôle strict de qui peut utiliser quoi et quand les restrictions.

Considérez l'extrait suivant -

fn main(){
   let v = vec![1,2,3]; 
   // vector v owns the object in heap

   //only a single variable owns the heap memory at any given time
   let v2 = v; 
   // here two variables owns heap value,
   //two pointers to the same content is not allowed in rust

   //Rust is very smart in terms of memory access ,so it detects a race condition
   //as two variables point to same heap

   println!("{:?}",v);
}

L'exemple ci-dessus déclare un vecteur v. L'idée de propriété est qu'une seule variable se lie à une ressource, soit v se lie à la ressource ou v2se lie à la ressource. L'exemple ci-dessus génère une erreur - utilisation de la valeur déplacée: `v` . En effet, la propriété de la ressource est transférée vers la v2. Cela signifie que la propriété est déplacée de v à v2 (v2 = v) et v est invalidé après le déplacement.

Passer de la valeur à une fonction

La propriété d'une valeur change également lorsque nous transmettons un objet du tas à une fermeture ou à une fonction.

fn main(){
   let v = vec![1,2,3];     // vector v owns the object in heap
   let v2 = v;              // moves ownership to v2
   display(v2);             // v2 is moved to display and v2 is invalidated
   println!("In main {:?}",v2);    //v2 is No longer usable here
}
fn display(v:Vec<i32>){
   println!("inside display {:?}",v);
}

Renvoyer la valeur d'une fonction

La propriété transmise à la fonction sera invalidée à la fin de l'exécution de la fonction. Une solution pour cela est de laisser la fonction renvoyer l'objet possédé à l'appelant.

fn main(){
   let v = vec![1,2,3];       // vector v owns the object in heap
   let v2 = v;                // moves ownership to v2
   let v2_return = display(v2);    
   println!("In main {:?}",v2_return);
}
fn display(v:Vec<i32>)->Vec<i32> { 
   // returning same vector
   println!("inside display {:?}",v);
}

Propriété et types primitifs

Dans le cas des types primitifs, le contenu d'une variable est copié dans une autre. Il n'y a donc pas de transfert de propriété. C'est parce qu'une variable primitive a besoin de moins de ressources qu'un objet. Prenons l'exemple suivant -

fn main(){
   let u1 = 10;
   let u2 = u1;  // u1 value copied(not moved) to u2

   println!("u1 = {}",u1);
}

La sortie sera - 10.