Что такое r # "# # оператор в Rust?
Я видел оператор r#""
в Rust, но я не могу найти, что он делает. Это пригодилось для создания JSON:
let var1 = "test1";
let json = r#"{"type": "type1", "type2": var1}"#;
println!("{}", json) // => {"type2": "type1", "type2": var1}
Какое имя оператора r#""
? Как сделать var1
оценкой?
Ответы
Ответ 1
Я не могу найти, что он делает
Это связано с строковыми литералами и необработанными строками. Я думаю, что это хорошо объясняется в этой части документации, в блоке кода, который размещен там, вы можете видеть, что он делает:
"foo"; r"foo"; // foo
"\"foo\""; r#""foo""#; // "foo"
"foo #\"# bar";
r##"foo #"# bar"##; // foo #"# bar
"\x52"; "R"; r"R"; // R
"\\x52"; r"\x52"; // \x52
Это отрицает необходимость избегать специальных символов внутри строки.
Ответ 2
Символ r
в начале строкового литерала обозначает строковый литерал. Это не оператор, а префикс.
В обычной строковой литерал, есть некоторые символы, которые вам нужно бежать, чтобы сделать их частью строки, такие как "
и \
. "
Символ должен быть экранирован, потому что в противном случае прекратить строку, а \
должна быть сбежал, потому что это символ escape.
В сырых строковых литералах вы можете поместить произвольное количество символов #
между r
и открытием "
. Чтобы закрыть строковый литерал, вы должны иметь закрытие "
, за которым следует такое же количество #
символов, что и в начале, С нулем или более #
символами, вы можете поместить буквенные \
символов в строке (\
символы не имеют никакого специального значения). С одним или более #
символов, вы можете поместить буквенные "
символы в строке. Если вам нужно "
следует последовательность #
символов в строке, просто использовать один и тот же номер #
символов плюс один разграничить строку. Например: r##"foo #"# bar"##
представляет строку foo #"# bar
. Литерал не останавливается на цитате посередине, потому что за ней следует только один #
, тогда как литерал запускается с двумя #
.
Чтобы ответить на последнюю часть вашего вопроса, нет способа получить строковый литерал, который оценивает переменные в текущей области. Некоторые языки, такие как PHP, поддерживают это, но не Rust. Вы должны использовать format!
макро. Обратите внимание, что для JSON вам все равно нужно удвоить фигурные скобки, даже в строчном литерале, потому что строка интерпретируется макросом.
fn main() {
let var1 = "test1";
let json = format!(r#"{{"type": "type1", "type2": {}}}"#, var1);
println!("{}", json) // => {"type2": "type1", "type2": test1}
}
Если вам нужно создать много JSON, есть много ящиков, которые облегчат вам работу. В частности, с помощью serde_json
вы можете определить регулярные структуры или перечисления Rust и автоматически их преобразовать в JSON.
Ответ 3
Впервые я увидел эту странную нотацию в руководствах по glium (старый ящик для управления графикой) и используется для "инкапсуляции" и передачи кода GLSL (язык GL Shading) в шейдеры графического процессора
https://github.com/glium/glium/blob/master/book/tuto-02-triangle.md
Насколько я понимаю, похоже, что содержимое r #... # осталось нетронутым, оно никак не интерпретируется. Отсюда и сырая строка.