Comment obtenir &'static str à partir de String en Rust : guide complet avec exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi est-ce un problème ?

\n

Si vous avez déjà écrit quelque chose de plus complexe que "Hello, World!" en Rust, vous avez sûrement rencontré une situation où le compilateur vous crie littéralement : "expected &'static str, but found String". Ça vous dit quelque chose ? C'est l'une des questions les plus populaires sur Stack Overflow (des dizaines de milliers de vues), et ce n'est pas pour rien.

\n

Le problème est que String et &'static str sont deux bêtes différentes. String est un type propriétaire qui peut croître et changer pendant l'exécution. Tandis que &'static str est une référence à une tranche de chaîne qui vit pendant toute la durée du programme. C'est comme comparer une valise avec des affaires (String) à une étagère fixée à vie (&'static str).

\n

Dans ce tutoriel, nous allons passer en revue toutes les méthodes légales pour transformer String en &'static str, des plus simples aux plus avancées. Et oui, je vais vous montrer comment ne pas vous tirer une balle dans le pied en cours de route.

\n\n

Qu'est-ce que &'static str en réalité ?

\n

Avant de coder, comprenons la théorie. &'static str est une référence à une chaîne qui vit pendant toute la durée d'exécution du programme. Ces chaînes sont généralement intégrées directement dans le binaire :

\n
let hello: &'static str = "Hello, world!"; // Vit éternellement\n
\n

Mais que faire si la chaîne est créée dynamiquement ? Par exemple, lue depuis un fichier ou reçue depuis le réseau ? C'est là que les choses deviennent intéressantes.

\n\n

Méthode n°1 : La plus simple — la fuite mémoire (oui, c'est légal)

\n

Oui, vous avez bien entendu. Rust permet une fuite mémoire intentionnelle via la fonction Box::leak. Ce n'est pas un bug, c'est une fonctionnalité ! Vous dites littéralement au compilateur : "Oublie cette mémoire, elle est à moi pour toujours".

\n
use std::boxed::Box;\n\nfn string_to_static_str(s: String) -> &'static str {\n    // Transforme String en Box<str>, puis "oublie" la boîte\n    let boxed_str: Box<str> = s.into_boxed_str();\n    // Maintenant, cette chaîne vivra éternellement\n    Box::leak(boxed_str)\n}\n\nfn main() {\n    let dynamic_string = String::from("Je suis né dynamiquement !");\n    let static_ref: &'static str = string_to_static_str(dynamic_string);\n    println!("{}", static_ref);\n    // La mémoire ne sera jamais libérée\n}\n
\n

Avantages : Simple, efficace, ne nécessite pas de crates externes.
\nInconvénients : Vous perdez définitivement le contrôle de la mémoire. Si vous appelez cela dans une boucle — bonjour, OOM (Out of Memory).

\n\n

Quand est-ce approprié ?

\n
    \n
  • Lorsque vous savez avec certitude que la chaîne est nécessaire pendant toute la durée de vie du programme (par exemple, une configuration chargée une seule fois au démarrage).
  • \n
  • Dans les systèmes embarqués, où il n'y a pas de tas et tout est statique.
  • \n
\n\n

Méthode n°2 : Lazy Static — pour les paresseux et les intelligents

\n

La crate lazy_static est un classique de Rust. Elle permet de créer une variable statique qui n'est initialisée qu'à la première utilisation. Idéal pour les configurations et les données globales.

\n
// Ajoutez dans Cargo.toml : lazy_static = "1.4"\nuse lazy_static::lazy_static;\n\nlazy_static! {\n    static ref MY_STRING: String = {\n        // Supposons que nous lisons une chaîne depuis un fichier\n        String::from("Chargé paresseusement !")\n    };\n}\n\nfn get_static_str() -> &'static str {\n    // lazy_static donne automatiquement un &'static str\n    &MY_STRING\n}\n\nfn main() {\n    println!("{}", get_static_str());\n}\n
\n

Avantages : \n

    \n
  • Sûr (pas de fuite mémoire).
  • \n
  • Initialisation paresseuse — la chaîne n'est créée que lorsque nécessaire.
  • \n
  • Fonctionne avec n'importe quel type, pas seulement les chaînes.
  • \n
\nInconvénients : \n
    \n
  • Dépendance à une crate externe.
  • \n
  • Peut être excessif pour des cas simples.
  • \n
\n

\n\n

Méthode n°3 : OnceCell et OnceLock — l'alternative moderne

\n

Depuis Rust 1.70, dans la sta

Blogs

Book Recommendations