Rust中的 r#""# 运算符是什么?

138

我在Rust中看到了操作符r#"",但我找不到它的用途。这对创建JSON很有帮助:

我看到了操作符r#"",但我不知道它的作用是什么。它在创建JSON时非常有用:

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

操作符r#""的名称是什么?如何使var1得到计算结果?

3个回答

137

我找不到它的作用

这与字符串字面量和原始字符串有关。我认为在文档的这个部分中已经很好地解释了它的作用,在那里发布的代码块中,您可以看到它的作用:

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

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

"\x52"; "R"; r"R";                 // R
"\\x52"; r"\x52";                  // \x52
它消除了在字符串内转义特殊字符的需要。

124

字符串字面值开头的r字符表示原始字符串字面值。它不是运算符,而是前缀。

在普通字符串字面值中,有一些字符需要转义才能成为字符串的一部分,例如"\。需要转义"字符,因为它会结束字符串,需要转义\,因为它是转义字符。

在原始字符串字面值中,你可以在 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。

5
我第一次看到这种奇怪的符号是在glium教程中(一个旧的图形管理库),它被用来“封装”和传递GLSL代码(GL着色语言)给GPU的着色器。

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

据我了解,r#...#的内容似乎没有被修改,也没有进行任何解释。因此称为原始字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接