String vs str en Rust : pourquoi les débutants se trompent et comment comprendre une fois pour toutes
\n\nSi vous commencez tout juste à apprendre Rust, vous avez sûrement déjà rencontré cette situation : le compilateur râle, vous essayez de passer un String là où un &str est attendu, ou l'inverse. Cela vous dit quelque chose ? C'est l'une des questions les plus populaires sur Stack Overflow (des milliers de vues !), et ce n'est pas pour rien — le sujet est vraiment fondamental pour comprendre la gestion de la mémoire en Rust.
Dans cet article, nous allons voir en quoi String et &str diffèrent, quand utiliser chaque type, et comment éviter les erreurs typiques. C'est parti !
Réponse courte pour ceux qui sont pressés
\n\nSi vous avez besoin d'une réponse immédiate — retenez l'essentiel :
\n\n- \n
Stringest un type de données propriétaire, mutable et dynamique, stocké dans le tas (heap). \n&strest une tranche de chaîne immuable (slice) qui fait référence à des données appartenant à quelqu'un d'autre. On le rencontre le plus souvent sous la forme&str. \n
Maintenant, approfondissons.
\n\nQu'est-ce que String en Rust ?
\n\nString est un type qui possède ses données. Lorsque vous créez une String, la mémoire est allouée dans le tas, et la chaîne peut s'allonger, se réduire ou être modifiée.
let mut s = String::from("Bonjour");\ns.push_str(", le monde !");\nprintln!("{}", s); // Affiche : Bonjour, le monde !\n\nIci, s est le propriétaire de la chaîne. Lorsque s sort de la portée, la mémoire est automatiquement libérée (merci RAII — Resource Acquisition Is Initialization).
Caractéristiques principales de String :
\n- \n
- Possède les données (owning type) \n
- Mutable \n
- Stockée dans le tas \n
- Peut être créée à partir d'un littéral de chaîne :
String::from("texte")\n - Prend en charge la concaténation, l'insertion, la suppression de caractères \n
Qu'est-ce que &str en Rust ?
\n\n&str (prononcé "tranche-str" ou "string slice") est une référence à une séquence de caractères UTF-8 qui appartient à quelqu'un d'autre. En soi, &str n'est qu'un pointeur vers les données et une longueur.
let greeting: &str = "Bonjour";\nprintln!("{}", greeting);\n\nDans cet exemple, greeting est une référence à un littéral de chaîne stocké directement dans le fichier binaire du programme (dans le segment mémoire en lecture seule). greeting ne possède pas ces données — il les regarde simplement.
Caractéristiques principales de &str :
\n- \n
- Ne possède pas les données (borrowed type) \n
- Immuable \n
- Stocké soit dans le binaire (littéraux de chaîne), soit dans le tas (comme une tranche de
String) \n - Léger — composé de deux champs : pointeur + longueur (16 octets sur un système 64 bits) \n
- Idéal pour passer aux fonctions lorsqu'on n'a pas besoin de modifier la chaîne \n
Différences clés entre String et &str (tableau)
\n\nRésumons tout cela dans un tableau clair :
\n\n| Caractéristique | \nString | \n&str | \n
|---|---|---|
| Possession | \nPossède les données | \nEmprunte les données | \n
| Mutabilité | \nOui (mut) | \nNon | \n
| Où est stocké | \nTas (heap) | \nTas, pile ou binaire | \n
| Taille dans la pile | \n24 octets (ptr + len + cap) | \n16 octets (ptr + len) | \n
| Création | \nString::from("...") | \n"..." ou &s[..] | \n
| Utilisation principale | \nQuand on doit modifier ou
BlogsBook RecommendationsLire aussi |