Syntaxe de base de Rust
Les variables, les types de base, les fonctions, les commentaires et le flux de contrôle sont des concepts de programmation présents dans presque tous les langages de programmation.
Ces concepts fondamentaux seront présents dans chaque programme Rust. Les apprendre tôt vous permettra d'apprendre à utiliser Rust aussi rapidement que possible.
Variables
Tout d'abord, il faut noter que Rust est un langage à typage fort, mais il a la capacité de déduire automatiquement le type des variables. Cela peut facilement être confondu avec des langages à typage faible.
Par défaut, les variables en Rust sont immuables, sauf si elles sont déclarées comme mutables à l'aide du mot-clé `mut`.
let a = 123; // 不可变变量 let mut b = 10; // 可变变量
Pour déclarer une variable, vous devez utiliser leletmot-clé. Par exemple :
let a = 123;
Les développeurs qui n'ont appris que JavaScript sont très sensibles à cette affirmation, tandis que les développeurs qui n'ont appris que C ont du mal à la comprendre.
Après cette déclaration, les trois lignes de code suivantes sont toutes interdites :
a = "abc"; a = 4.56; a = 456;
L'erreur de la première ligne est qu'après avoir déclaré `a` comme 123, `a` est déterminé comme étant un entier, et vous ne pouvez pas lui affecter une valeur de chaîne.
L'erreur de la deuxième ligne est qu'une conversion automatique entraînerait une perte de précision numérique, et Rust n'autorise pas les conversions de type automatiques qui perdent de la précision.
L'erreur de la troisième ligne est que `a` n'est pas une variable mutable.
Les deux premières erreurs sont faciles à comprendre, mais que signifie la troisième ? `a` n'est-il pas une variable ?
Cela est lié à la conception de Rust pour la sécurité en haute concurrence : au niveau du langage, il essaie de minimiser les situations où les valeurs des variables peuvent être modifiées. Ainsi, la valeur de `a` est immuable. Mais cela ne signifie pas que `a` n'est pas une « variable » (le mot anglais `variable`) ; la documentation officielle appelle les variables comme `a` des « variables immuables ».
Si une partie de notre programme s'exécute en supposant qu'une valeur ne changera jamais, tandis qu'une autre partie de notre code modifie cette valeur, alors la première partie peut ne pas se comporter comme prévu. Les erreurs causées par cela sont difficiles à trouver par la suite. C'est la raison pour laquelle Rust a conçu ce mécanisme.
Bien sûr, rendre une variable « mutable » ne nécessite que lemutmot-clé.
let mut a = 123; a = 456;
Ce programme est correct.
Différence entre les constantes et les variables immuables
Puisque les variables immuables sont immuables, ne sont-elles pas simplement des constantes ? Pourquoi sont-elles appelées variables ?
Il existe toujours une différence entre les variables et les constantes. En Rust, le programme suivant est valide :
let a = 123; // 可以编译,但可能有警告,因为该变量没有被使用 let a = 456;
Mais si `a` est une constante, c'est invalide :
const a: i32 = 123; let a = 456;
La valeur d'une variable peut être « reliée à nouveau », mais elle ne peut pas être modifiée d'elle-même avant d'être « reliée à nouveau ». Cela garantit que, dans chaque région après une « liaison », le compilateur peut raisonner pleinement sur la logique du programme. Bien que Rust dispose d'une inférence de type automatique, dans certains cas, déclarer le type est plus pratique :
let a: u64 = 123;
Ici, `a` est déclaré comme une variable entière non signée de 64 bits. Si le type n'était pas déclaré, `a` serait automatiquement inféré comme une variable entière signée de 32 bits, ce qui a un impact significatif sur la plage de valeurs que `a` peut contenir.
Types de données
Rust est un langage à typage statique. Vous pouvez spécifier explicitement les types lors de la déclaration de variables, mais vous pouvez généralement vous fier à l'inférence de type.
Types de base :i32 (entier signé 32 bits), u32 (entier non signé 32 bits), f64 (nombre à virgule flottante 64 bits), bool (booléen), char (caractère)
Exemple
let y: f64 = 3.14;
let is_true: bool = true;
let letter: char = 'A';
Fonctions
Les fonctions Rust sont définies à l'aide du mot-cléfn, et le type de retour est spécifié à l'aide du symbole flèche->.
Exemple
a + b
}
Si une fonction n'a pas de valeur de retour, le type par défaut est()(c'est-à-dire le tuple vide).
Flux de contrôle
expression `if`
Exemple
if number < 5 {
println!("inférieur à 5");
} else {
println!("supérieur ou égal à 5");
}
boucle `loop` :`loop` est une boucle infinie en Rust ; vous pouvez utiliser `break` pour sortir de la boucle.
Exemple
loop {
counter += 1;
if counter == 10 {
break;
}
}
boucle `while`
Exemple
while number != 0 {
println!("{}!", number);
nombre -= 1;
}
boucle `for`
Exemple
println!("{}!", number);
}
Propriété
La propriété en Rust est un mécanisme unique de gestion de la mémoire. Ses concepts clés incluent la propriété, l'emprunt et les références.
Règles de propriété :
- Chaque valeur en Rust a un seul propriétaire.
- Chaque valeur ne peut avoir qu'un seul propriétaire à un instant donné.
- Lorsque le propriétaire sort de la portée, la valeur sera libérée.
let s1 = String::from("hello");
let s2 = s1; // s1 的所有权被转移给了 s2
// println!("{}", s1); // 此处编译会报错,因为 s1 已不再拥有该值Emprunt et références :L'emprunt vous permet de référencer des données sans en prendre possession, mis en œuvre via le&symbole.
fn main() {
let s = String::from("hello");
let len = calculate_length(&s); // 借用
println!("The length of '{}' is {}.", s, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
Structures
Les structures sont utilisées pour créer des types personnalisés, et leurs champs peuvent contenir plusieurs types de données.
Exemple
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
let user1 = User {
username: String::from("someusername"),
email: String::from("[email protected]"),
sign_in_count: 1,
active: true,
};
Énumérations
Les énumérations vous permettent de définir un type de données parmi plusieurs possibles.
Exemple
V4,
V6,
}
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
Filtrage par motif (match)
`match` est un puissant outil de contrôle de flux en Rust, semblable à une instruction `switch`.
Exemple
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
Gestion des erreurs
Rust dispose de deux façons principales de gérer les erreurs :Result<T, E>etOption<T>。
Résultat :
Exemple
OK(T),
Err(E),
}
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err(String::from("Division par zéro"))
} else {
OK(a / b)
}
}
Option :
Exemple
if index < vec.len() {
Some(vec[index])
} else {
Aucune
}
}
Durées de vie de la propriété et de l'emprunt
Rust utilise les durées de vie pour garantir que les références sont valides. Les annotations de durée de vie sont notées par'aetc., mais dans les cas courants, le compilateur les inférera automatiquement.
Exemple
if x.len() > y.len() {
x
} else {
y
}
}
Masquage
Le concept de masquage est différent de « override » ou « overload » dans d'autres langages orientés objet. Le masquage est ce qui était appelé « rebinding » précédemment ; les guillemets ont été utilisés pour désigner le concept avant son introduction.
Le masquage désigne le mécanisme par lequel le nom d'une variable peut être réutilisé :
Exemple
let x = 5;
let x = x + 1;
let x = x * 2;
println!("La valeur de x est : {}", x);
}
La sortie de ce programme est :
The value of x is: 12
Le masquage n'est pas le même concept que l'affectation à une variable mutable. Le masquage signifie utiliser le même nom pour représenter une autre entité de variable, et son type, sa mutabilité et sa valeur peuvent tous changer. Cependant, l'affectation à une variable mutable ne peut changer que sa valeur.
let mut s = "123"; s = s.len();
Ce programme provoquera une erreur : vous ne pouvez pas affecter une valeur entière à une variable de chaîne de caractères.
Autres extensions