diff --git a/essential_rust.tex b/essential_rust.tex index a1b38eba34d3d488bec0eb087370de459bbb3bcf..7fa5c5e7721475ce96d2c715af3b7c5e8149d6fc 100644 --- a/essential_rust.tex +++ b/essential_rust.tex @@ -996,35 +996,95 @@ fn read_file() -> Result<String, io::Error> { Tous les programmes doivent gérer la façon dont ils utilisent la mémoire. \begin{itemize} - \item Certains langages, comme Java ou Go, utilisent un ramasse-miette détectant la mémoire qui n'est plus utilisée. - \item D'autres langages, comme le C, requiert que le développeur explicite l'allocation et la désallocation de la mémoire. + \item Certains langages comme Java ou Go ou OCaml, utilisent un ramasse-miette + détectant la mémoire qui n'est plus utilisée. + \item D'autres comme le C ou l'assembleur, requierent que le développeur + gère explicitement l'allocation et la désallocation de la mémoire. \end{itemize} +La première approche a l'inconvénient de causer des chutes de performance quand le +ramasse-miettes s'exécute, et nécessite souvent que tous les objets se trouvent +derrière une couche supplémentaire de pointeurs. -Rust utilise une autre approche : la mémoire est gérée par un système d'appartenance que le compilateur va vérifier à la compilation. +La seconde est source de bugs.\\ -Le système d'appartenance a trois règles : +Rust utilise une autre approche : la mémoire est gérée par un système d'appartenance +qui est vérifié à la compilation et qui permet de décider déterministiquement +à quel moment chaque valeur est libérée.\\ + +Le système d'appartenance a des règles strictes : \begin{itemize} - \item chaque valeur en Rust a une variable correspondante, appelée le propriétaire (owner). - \item il ne peut y avoir qu'un seul propriétaire à la fois. - \item quand le propriétaire sort du scope, la valeur va être libérée. + \item une valeur peut être propriétaire d'autres valeurs + \item toute valeur a un propriétaire unique + \item si une valeur cesse d'exister alors toutes les valeurs dont elle est + propriétaire cessent aussi d'exister \end{itemize} +Les références sont un ajout à ce système qui permet de ``prêter'' un accès +à un objet en en gardant la possession. +\newpage \begin{lstlisting}[style=Rust, language=Rust] fn main() { + let s1 = String::from("Hello World"); + // possession: s1 + // droit d'écriture: personne + // droit de lecture: s1 + + let s2 = s1; + // possession: s2 + // droit d'écriture: personne + // droit de lecture: s2 + // -> s1 a cédé tous ses droit à s2 + { - // \textbf{s} est une chaîne de caractères explicitement alloué dans le tas - let s = String::from("Hello world"); + let mut s3 = s2; + // possession: s3 + // droit d'écriture: s3 + // droit de lecture: s3 + + { + let r = &mut s3; + // possession: s3 + // droit d'écriture: r + // droit de lecture: r + // -> s3 a cédé ses droits d'écriture à r, mais a gardé la possession + } // r cesse d'exister + // possession: s3 + // droit d'écriture: s3 + // droit de lecture: s3 + // -> s3 récupère tous les droits après la fin du prêt à r + + { + let r1 = &s3; + let r2 = &s3; + // possession: s3 + // droit d'écriture: personne + // droit de lecture: r1, r2 + // -> un droit de lecture peut être prêté à plusieurs personnes en même temps + // -> personne ne peut écrire pendant ce temps + } // r1 et r2 cessent d'exister + // possession: s3 + // droit d'écriture: s3 + // droit de lecture: s3 + } + // r3 possesseur actuel de la chaîne cesse d'exister + // la chaîne n'a plus aucun possesseur, et la mémoire est donc libérée +} +\end{lstlisting} - // Utilisation de \textbf{s} - println!("{}", s); // "Hello world" +La libération se fait grâce à l'appel de \texttt{drop} dans le trait \texttt{std::ops::Drop}.\\ - } // \textbf{s} est libéré +Grâce aux règles de possession, cette fonction est souvent très facile à implémenter : - // \textbf{s} n'est plus valide: Il est impossible de l'utiliser +\begin{lstlisting}[style=Rust, language=Rust] +impl std::ops::Drop for MonType { + fn drop(self) {} } \end{lstlisting} +La méthode \texttt{drop} prend possession de \texttt{self}... et ne fait rien d'autre : +\texttt{self} sera libéré, puisque son nouveau possesseur cessera d'exister à la +fin du corps de la fonction. + -La libération se fait grâce à l'appel de \texttt{drop()}, cette fonction sur la structure \texttt{String()} permet de libérer la mémoire. \newpage