diff --git a/essential_rust.tex b/essential_rust.tex index ddef1639800de597cb4917f08b27234dcdf95d88..1c9665a9f45f79c6e8777939d1321a0f89ef8c06 100644 --- a/essential_rust.tex +++ b/essential_rust.tex @@ -157,61 +157,89 @@ Quelques autres liens utiles : \subsection{Hello World!} \begin{lstlisting}[style=Rust, language=Rust] +// Dans le fichier \texttt{hello\_world.rs} fn main() { - println!("Hello World"); // "Hello World" + println!("Hello World"); } \end{lstlisting} -Pour compiler ce programme, on va directement utiliser \texttt{rustc}, grâce à la commande shell suivante : \texttt{rustc helloWorld.rs}. -Le binaire généré sera nommé en fonction du fichier. +Pour compiler ce programme on va directement utiliser \texttt{rustc}, avec la commande +shell suivante : + +\texttt{rustc hello\_world.rs} + +Le binaire généré sera nommé en fonction du fichier si on ne précise pas explicitement +un autre nom avec l'option \texttt{-o BINAIRE}. + +On peut ensuite exécuter normalement \texttt{./hello\_world} qui affichera le texte +\texttt{Hello World} (avec un retour à la ligne). \subsection{Quelques notions basiques} -Il existe les types numériques suivants en Rust : +Comme C, Rust a de nombreux types numériques de différentes tailles. Contrairement à C +les noms sont unifiés : \texttt{i}/\texttt{u}/\texttt{f} pour ``integer'', ``unsigned integer'', +``floating point'', suivi du nombre de bits. \begin{itemize} - \item Entiers signés: \texttt{i8}, \texttt{i16}, \texttt{i32}, \texttt{i64} et \texttt{i128}. - \item Entiers non-signés: \texttt{u8}, \texttt{u16}, \texttt{u32}, \texttt{u64} et \texttt{u128}. - \item Flottants: \texttt{f32}, \texttt{f64}. - \item Entiers "tailles": \texttt{isize} et \texttt{usize}. (Équivalent de \texttt{intptr\_t} et \texttt{uintptr\_t}) + \item entiers signés : \texttt{i8}, \texttt{i16}, \texttt{i32}, \texttt{i64} et \texttt{i128}. + \item entiers non signés : \texttt{u8}, \texttt{u16}, \texttt{u32}, \texttt{u64} et + \texttt{u128}. + \item flottants : \texttt{f32}, \texttt{f64}. + \item entiers de la taille de la machine : \texttt{isize} et \texttt{usize}.\\ + (sont égaux à des \texttt{i32}/\texttt{u32} sur système 32 bits, et + \texttt{i64}/\texttt{u64} sur système 64 bits) \end{itemize} \begin{lstlisting}[style=Rust, language=Rust] fn main() { - // Par défaut, les variables sont non-modifiable (keyword \textbf{const} en C). - let x: i8 = 1; + // Par défaut, les variables sont non-modifiables (tout comme un \texttt{let} en OCaml). + let x: i8 = 1; // x vaut 1 - // \textit{variable shadowing} : nouvelle définition d'une même variable. - let x: i32 = 1; + // \texttt{let} peut redéfinir une variable qui écrase la précédente + let x = x + 1; // x vaut 2, le type est inféré à partir de l'expression - // Cette expression est donc impossible, car \textbf{x} ne peut pas être modifié. - // x = 2; + { + // une variable est visible uniquement à l'intérieur du bloc qui la définit + let x = 5; // x vaut 5 + let y = 4; // y vaut 4 + } + // x vaut de nouveau 2 + // y n'existe plus + + // pour mettre à jour une variable d'une manière visible en dehors du bloc, + // il faut la déclarer \texttt{mut} (mutable) // Le mot clé \textbf{mut} permet de rendre modifiable une variable. - let mut y: i32 = 1; - y = 4; + let mut z: i32 = 1; // similaire à \texttt{let z = ref 1} en OCaml + z = 4; + // \textit{Note :} ici le linter génère un avertissement que z n'a pas besoin + // d'être mutable et que sa première valeur 1 est inutile. - // Appel de fonction. - let result = add(x, y); + // z vaut 4 + { + z += 1; + } + // z vaut 5 - // La variable \textbf{result} n'a aucune annotation sur son type. - // En effet, le type de \textbf{result} est inféré depuis la signature de la fonction \textbf{add()}. + // Appel de fonction + // (la fonction peut être définie plus tard dans le fichier, + // il n'est pas nécessaire de la déclarer) + let result = add(x, y); // ici aussi le type est deviné grâce à la signature de add - // \textit{Note :} chaque exemple explicitera les types. + // \textit{Note :} dans ce document on explicitera les types plus que nécessaire + // la plupart des fonctions en Rust peuvent s'écrire avec pour unique annotation + // de type la signature de la fonction. println!("Result: {}", result); // "Result: 5" } // La fonction prend deux arguments qui sont des \textbf{i32} et retourne un \textbf{i32}. fn add(x: i32, y: i32) -> i32 { - return x + y; + x + y // pas besoin de mot-clé return, la dernière expression est renvoyée } \end{lstlisting} -Le linter inclus dans le compilateur va générer un avertissement sur la variable \texttt{y}, en précisant qu'il est inutile de faire le premier assignement. - -Le linter va même détecter qu'il est inutile de rendre \texttt{y} modifiable. \newpage