What is the r#""# operator in Rust?

StringRustSyntaxString Literals

String Problem Overview


I saw the operator r#"" in Rust but I can't find what it does. It came in handy for creating JSON:

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

What's the name of the operator r#""? How do I make var1 evaluate?

String Solutions


Solution 1 - String

> I can't find what it does

It has to do with string literals and raw strings. I think it is explained pretty well in this part of the documentation, in the code block that is posted there you can see what it does:

> "foo"; r"foo"; // foo > ""foo""; r#""foo""#; // "foo" >
> "foo #"# bar"; > r##"foo #"# bar"##; // foo #"# bar >
> "\x52"; "R"; r"R"; // R > "\x52"; r"\x52"; // \x52

It negates the need to escape special characters inside the string.

Solution 2 - String

The r character at the start of a string literal denotes a raw string literal. It's not an operator, but rather a prefix.

In a normal string literal, there are some characters that you need to escape to make them part of the string, such as " and \. The " character needs to be escaped because it would otherwise terminate the string, and the \ needs to be escaped because it is the escape character.

In raw string literals, you can put an arbitrary number of # symbols between the r and the opening ". To close the raw string literal, you must have a closing ", followed by the same number of # characters as there are at the start. With zero or more # characters, you can put literal \ characters in the string (\ characters do not have any special meaning). With one or more # characters, you can put literal " characters in the string. If you need a " followed by a sequence of # characters in the string, just use the same number of # characters plus one to delimit the string. For example: r##"foo #"# bar"## represents the string foo #"# bar. The literal doesn't stop at the quote in the middle, because it's only followed by one #, whereas the literal was started with two #.

To answer the last part of your question, there's no way to have a string literal that evaluates variables in the current scope. Some languages, such as PHP, support that, but not Rust. You should consider using the format! macro instead. Note that for JSON, you'll still need to double the braces, even in a raw string literal, because the string is interpreted by the macro.

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

If you need to generate a lot of JSON, there are many crates that will make it easier for you. In particular, with serde_json, you can define regular Rust structs or enums and have them serialized automatically to JSON.

Solution 3 - String

The first time I saw this weird notation is in glium tutorials (old crate for graphics management) and is used to "encapsulate" and pass GLSL code (GL Shading language) to shaders of the GPU

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

As far as I understand, it looks like the content of r#...# is left untouched, it is not interpreted in any way. Hence raw string.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIncertezaView Question on Stackoverflow
Solution 1 - StringTimView Answer on Stackoverflow
Solution 2 - StringFrancis GagnéView Answer on Stackoverflow
Solution 3 - StringbendegView Answer on Stackoverflow