URL: https://linuxfr.org/news/sortie-de-rust-en-version-0-3 Title: Sortie de Rust en version 0.3 Authors: claudex Bruno Michel, Pierre Jarillon, tuiu pol, Florent Zara, Benoît Sibaud, Nils Ratusznik, Xavier Teyssier et Benoît Date: 2012年07月15日T15:10:41+02:00 License: CC By-SA Tags: langage, programmation, mozilla, rust et ada Score: 35 Rust est un langage développé par la fondation Mozilla qui implémente les paradigmes procédural, orienté objet, concurrent et fonctionnel. C'est un langage compilé plutôt orienté bas-niveau et qui concurrence le C ou le C++. Il est multiplates-formes et tourne sous Linux, Mac OS X et Windows. Pour rappel, Rust est un langage de programmation système fortement typé. L'accent est mis sur la sûreté des accès mémoire et la concurrence. Vu les orientations de la fondation Mozilla, le but est de pouvoir développer un navigateur Web avec ce langage et les travaux ont déjà commencé, ce navigateur alternatif s'appelle [Servo](https://github.com/mozilla/servo). ![logo](http://upload.wikimedia.org/wikipedia/en/thumb/d/d5/Rust_programming_language_black_logo.svg/200px-Rust_programming_language_black_logo.svg.png) ---- [Site officiel ](http://www.rust-lang.org/) [Notes de version](https://github.com/mozilla/rust/blob/release-0.3/RELEASES.txt) [DLFP : Sortie de la version 0.1 de Rust](http://linuxfr.org/news/sortie-de-la-version-0-1-de-rust) ---- Beaucoup d'exemples ci-dessous sont tirés de la [documentation de Rust](http://dl.rust-lang.org/doc/rust.html) #Hello World! Le traditionnel Hello World : ```go import io::println; fn main() { println("Hello World !"); } ``` # Définition de variable # Les variables peuvent être définies localement (avec le mot-clef `let`) ou globalement. Pour les variables locales, il est possible d'utiliser l'inférence de type. Par défaut les variables locales sont définies immutables mais cela peut être changé grâce au mot-clef `mut` : ```go use std; const repeat: uint = 5u; fn main() { let hi = "Hi!"; let mut count = 0u; while count < repeat { io::println(hi); count += 1u; } let fl: float = 57.8; } ``` Il est aussi possible de définir une assignation conditionnelle : ```go let x = if the_stars_align() { 4 } else if something_else() { 3 } else { 0 }; ``` #Les fonctions Il est possible de définir des fonctions. Un point intéressant est que si vous définissez un type de retour de la fonction, le compilateur vérifiera que tous les chemins d'exécutions retourne bien un type. Une fonction sans type de retour est aussi possible, comme ci-dessus dans le Hello World. Voici une fonction qui additionne deux entiers et qui renvoie le résultat : ```go fn add(x: int, y: int) -> int { ret x + y; } ``` Il est aussi possible de définir des fonctions qui échouent tout le temps, ce sont des fonctions divergentes. L'intérêt est de pouvoir définir une fonction qui exécute une série d'instruction en cas d'erreur et de pouvoir l'utiliser dans une fonction qui a un type de retour sans que le compilateur râle. ```go fn my_err(s: str) -> ! { log(info, s); fail; } fn f(i: int) -> int { if i == 42 { ret 42; } else { my_err("Bad number!"); } } ``` Dans l'exemple ci-dessus le compilateur ne râlera pas même si la branche du `else` ne retourne aucun type. `fail` est utilisé en cas d'erreur et arrête l'exécution du programme. #Les boucles Les boucles `while` sont très classiques : ```go while i < 10 { println("hello\n"); i = i + 1; } ``` Par contre, il existe un type de boucle infinie en utilisant le mot-clef `loop`, par exemple : ```go fn count() -> bool { let mut i = 0; loop { i += 1; if i == 20 { ret true; } } } ``` Il existe aussi des boucles `for` qui sont moins traditionnelles car elle itèrent sur un vecteur ou une chaîne de caractères (semblable à ce qu'on trouve en Ruby ou Python par exemple) : ```go for 5.times { println("Here's some Rust!"); } let v: ~[foo] = ~[a, b, c]; for v.each |e| { bar(e); } ``` #Les tâches Rust utilise des tâches légères similaires à ce qu'on retrouve dans Erlang. Les tâches ne partagent pas de mémoire et la communication se fait par passage de message. Il est cependant possible de transmettre des données d'une tâche à l'autre via le tas d'échange, dans ce cas, la tâche qui donne les données ne peut plus y accéder. #Les pointeurs Rust fonctionne comme le C/C++ pour l'allocation de mémoire, c'est-à-dire que si vous déclarez une variable, elle sera allouée sur la pile et si vous copiez un enregistrement, tout l'enregistrement est copié, pas uniquement le pointeur. Pour les petits enregistrement, c'est souvent plus performant mais ça peux poser des problèmes de performances si la quantité de données à copier est importante. Heureusement, il est quand même possible d'utiliser les pointeurs, il en existe de différents types : ##Les boîtes partagées Ce sont des pointeurs alloués sur le tas et gérés avec un ramasse-miettes, il s'écrivent avec un `@`. La copie d'une boîte partagée ne copie que le pointeur, pas les données : ```go let x: @int = @10; // Nouvelle boîte, le compteur de référence est à 1 let y = x; // Copie le pointeur, incrémente le compteur de référence // Quand x et y sont hors de portée, le compteur de référence est à 0 et la boîte est libérée. ``` ##Les boîtes uniques Ce sont des boîtes qui ne peuvent être référencées que par une seule variable. Grâce à cela, elles peuvent être allouées sur un tas d'échange commun à toutes les tâches et peuvent être échangées entre les tâches. Lors de cet échange, la tâche qui donne le pointeur abandonne sa possession de la boîte. À cause de leur unicité, la copie d'une boîte unique ne peut se faire qu'explicitement en copiant toutes les données : ```go let x = ~10; let y = x; // erreur, copie implicite d'une boîte unique let y = copy x; // copie d'une boîte unique ``` Il est possible de déplacer l’appartenance d'une boîte à l'aide de l'opérateur de déplacement `->`, lors de cette opération, la boîte n'est plus accessible par la variable initiale. ```go let x = ~10; let y <- x; ``` ##Les pointeurs empruntés Ce sont l'équivalent des références en C++ mais avec la garantie de pointer vers une zone mémoire valide. Les pointeurs empruntés n'impliquent jamais la possession du pointeur comme c'est le cas avec les boîtes partagées. L'intérêt de ce type de pointeur est de pouvoir faire du passage d'argument par référence pour les pointeurs : ```go let foo = "foo"; work_with_foo_by_pointer(&foo); ``` ##Mutabilité Comme pour les variables, il existe une version *mutable* pour les pointeurs, cela permet de modifier les données pointées en déférençant le pointeur. ```go fn increase_contents(pt: @mut int) { *pt += 1; } ```

AltStyle によって変換されたページ (->オリジナル) /