web-dev-qa-db-fra.com

Qu'est-ce que l'opérateur r # "" # dans Rust?

J'ai vu l'opérateur r#"" in Rust mais je ne trouve pas ce qu'il fait. Il a été utile pour créer JSON:

let var1 = "test1";
let json = r#"{"type": "type1", "type2": var1}"#;
println!("{}", json) // => {"type2": "type1", "type2": var1}

Quel est le nom de l'opérateur r#""? Comment puis-je faire var1 évaluer?

45
アレックス

Je ne trouve pas ce que ça fait

Cela concerne les littéraux de chaîne et les chaînes brutes. Je pense que cela est assez bien expliqué dans cette partie de la documentation , dans le bloc de code qui y est affiché, vous pouvez voir ce qu'il fait:

"foo"; r"foo";                     // foo
"\"foo\""; r#""foo""#;             // "foo"

"foo #\"# bar";
r##"foo #"# bar"##;                // foo #"# bar

"\x52"; "R"; r"R";                 // R
"\\x52"; r"\x52";                  // \x52

Cela annule la nécessité d'échapper les caractères spéciaux à l'intérieur de la chaîne.

47
Tim Castelijns

Le caractère r au début d'un littéral de chaîne indique un littéral de chaîne brut . Ce n'est pas un opérateur, mais plutôt un préfixe.

Dans un littéral de chaîne normal, vous devez échapper certains caractères pour les intégrer à la chaîne, tels que " Et \. Le caractère " Doit être échappé car cela terminerait autrement la chaîne, et le \ Doit être échappé car il s'agit du caractère d'échappement.

Dans les littéraux de chaîne bruts, vous pouvez mettre un nombre arbitraire de symboles # Entre le r et l'ouverture ". Pour fermer le littéral de chaîne brut, vous devez avoir un " De fermeture, suivi du même nombre de caractères # Qu'au début. Avec zéro ou plusieurs caractères #, Vous pouvez mettre des caractères littéraux \ Dans la chaîne (les caractères \ N'ont pas de signification particulière). Avec un ou plusieurs caractères #, Vous pouvez mettre des caractères littéraux " Dans la chaîne. Si vous avez besoin d'un " Suivi d'une séquence de # Caractères dans la chaîne, utilisez simplement le même nombre de # Caractères plus un pour délimiter la chaîne. Par exemple: r##"foo #"# bar"## Représente la chaîne foo #"# bar. Le littéral ne s'arrête pas à la citation du milieu, car il n'est suivi que d'un #, Alors que le littéral a commencé avec deux #.

Pour répondre à la dernière partie de votre question, il n'y a aucun moyen d'avoir un littéral de chaîne qui évalue les variables dans la portée actuelle. Certains langages, tels que PHP, prennent en charge cela, mais pas Rust. Vous devriez envisager d'utiliser la macro format! à la place. Notez que pour JSON, vous devrez toujours doubler les accolades, même dans un littéral de chaîne brut, car la chaîne est interprétée par la macro.

fn main() {
    let var1 = "test1";
    let json = format!(r#"{{"type": "type1", "type2": {}}}"#, var1);
    println!("{}", json) // => {"type2": "type1", "type2": test1}
}

Si vous avez besoin de générer beaucoup de JSON, il existe de nombreuses caisses qui vous faciliteront la tâche . En particulier, avec serde_json , vous pouvez définir des structures ou des énumérations régulières Rust et les faire sérialiser automatiquement en JSON).

44
Francis Gagné

La première fois que j'ai vu cette notation bizarre est dans des tutoriels glium (ancienne caisse pour la gestion graphique) et est utilisée pour "encapsuler" et passer du code GLSL (langage GL Shading) aux shaders du GPU

https://github.com/glium/glium/blob/master/book/tuto-02-triangle.md

Pour autant que je sache, il semble que le contenu de r # ... # reste inchangé, il n'est interprété en aucune façon. D'où chaîne brute .

0
bendeg