多行字符串文字的语法是什么?

Dum*_*les 95 string rust

我很难弄清楚Rust中的字符串语法是如何工作的.具体来说,我试图找出如何制作多行字符串.

huo*_*uon 124

所有字符串文字都可以跨越多行,例如

let string = "line one
line two";
Run Code Online (Sandbox Code Playgroud)

是一个两行字符串,相同"line one\nline two"(当然也可以\n直接使用换行符).如果您希望仅为了格式化原因而跨越多行来断开字符串,则可以使用\例如以下内容来转义换行符和前导空格

let string = "one line \
    written over \
    several";
Run Code Online (Sandbox Code Playgroud)

是一样的"one line written over several".

  • 如果只是可读性问题,我想添加 `concat!()` 宏来完成给定的选项(https://doc.rust-lang.org/std/macro.concat.html) (8认同)
  • @theberzi,是的,保留空格的唯一方法是将其放置在 \\ 之前,因为所有前导空格都会在下一行被吃掉。 (3认同)

c0g*_*c0g 61

如果你想做一些更长的事情,可能包括引号,反斜杠等,也可以使用原始字符串文字表示法:

let shader = r#"
    #version 330

    in vec4 v_color;
    out vec4 color;

    void main() {
        color = v_color;
    };
"#;
Run Code Online (Sandbox Code Playgroud)

如果字符串中包含双引号和散列符号序列,则可以将任意数量的散列表示为分隔符:

let crazy_raw_string = r###"
    My fingers #"
    can#"#t stop "#"" hitting
    hash##"#
"###;
Run Code Online (Sandbox Code Playgroud)

  • 这将有助于显示打印这些字符串的输出。从答案本身我无法判断换行会发生什么,以及如何处理缩进。 (7认同)
  • 但是...如果您不希望结果中出现换行符,您只需要转义换行符,而原始字符串对此无济于事。 (2认同)
  • 如果您不关心换行符(例如当您嵌入与换行符无关的代码(如着色器和内核)),或者正如您提到的那样,原始字符串只是阻止您在每行末尾添加“\”当确实需要换行符时。它只是使您可以更轻松地嵌入您可能想要编辑的代码,而不必为每行末尾的“\”而烦恼。就这样。 (2认同)
  • 如果您希望(或不介意)结果字符串中出现换行符,则纯双引号字符串会非常好,如其他示例所示。如果你想避免换行,原始字符串是不好的。它们实际上只有在文本包含引号、反斜杠等时才有帮助——就像嵌入源代码中可能发生的那样。 (2认同)
  • 我看到你现在得到的东西,你是绝对正确的. (2认同)

dto*_*nay 40

Huon的答案是正确的,但如果缩进困扰你,请考虑使用Indoc,它是缩进多行字符串的过程宏.它代表"缩进文档".它提供了一个调用的宏indoc!(),它接受多行字符串文字并取消缩进,以便最左边的非空格字符位于第一列.

let s = indoc!("
          line one
          line two");
Run Code Online (Sandbox Code Playgroud)

结果是"line one\nline two".

如果您愿意,可以使用几种等效方法来格式化相同的内容,因此请选择您喜欢的方法.以下两者都会产生与上面相同的字符串.内容可以根据需要缩进 - 它不必是特定数量的空格.

let s = indoc!(
         "line one
          line two");

let s = indoc!("line one
                line two");
Run Code Online (Sandbox Code Playgroud)

相对于文档中最左边的非空格字符保留空白,因此以下行相对于第一行有两行缩进的3个空格:

let s = indoc!("
          line one
             line two");
Run Code Online (Sandbox Code Playgroud)

结果是"line one\n line two".

  • 啊! 非常感谢!当我在这里偶然发现你的答案时,我正要创建自己的问题,特别是关于使用缩进进行多行字符串文字的最佳方法,这也很好地保留了代码缩进!作为参考,我创建了一个 Rust 游乐场,其中列出了我提出的各种选项及其相对缺点:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c9ca0febb5f154e30811806873e38716 (3认同)
  • 这个问题几乎在我使用过的每一种语言中都困扰着我,而且总是有一些不同的方法来解决它。非常喜欢能够使用如此友好的宏!TY。 (2认同)

phi*_*611 12

如果您想在不使用外部 crate 的情况下对带有换行符的多行字符串中的空格进行精细控制,您可以执行以下操作。示例取自我自己的项目。

impl Display for OCPRecData {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "OCPRecData {{\n\
            \x20   msg: {:?}\n\
            \x20   device_name: {:?}\n\
            \x20   parent_device_name: {:?}\n\
        }}", self.msg, self.device_name, self.parent_device_name)
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是

OCPRecData {
    msg: Some("Hello World")
    device_name: None
    parent_device_name: None
}
Run Code Online (Sandbox Code Playgroud)
  • \n\ 在每个代码行的末尾在适当的位置创建一个换行符并丢弃这行代码中的更多空格
  • \x20 (十六进制;十进制 32)是一个 ASCII 空格,也是字符串这一行中要保留的第一个空格的指示符
  • \x20\x20\x20\x20并且\x20 有同样的效果


小智 7

如果您想缩进代码中的多行文字:

let s = "first line\n\
    second line\n\
    third line";

println!("Multiline text goes next:\n{}", s);
Run Code Online (Sandbox Code Playgroud)

结果将如下所示:

let s = "first line\n\
    second line\n\
    third line";

println!("Multiline text goes next:\n{}", s);
Run Code Online (Sandbox Code Playgroud)

  • 请使用散文“明确”说明哪段代码对此行为很重要。 (2认同)
  • 此注释建议一种将已接受答案中的两点结合的方法:如何生成多行字符串,在代码中以多行形式编写,但出于风格或易读性的原因,同时允许它自己的代码缩进形式,而该缩进形式不以最终字符串结尾。在文本中并没有非常清楚地说明它,但这是一个常见的用例,因此是一个有价值的建议。(有关此包装箱的版本,请参见dtolnay的答案。) (2认同)