Wie lautet die Syntax für ein mehrzeiliges String-Literal?

Antworten:

172

Alle Zeichenfolgenliterale können in mehrere Zeilen unterteilt werden. beispielsweise:

let string = "line one
line two";

ist eine zweizeilige Zeichenfolge, die gleiche wie "line one\nline two"(natürlich kann man den \nZeilenumbruch auch direkt verwenden). Wenn Sie aus Formatierungsgründen nur eine Zeichenfolge über mehrere Zeilen hinweg unterbrechen möchten, können Sie die neue Zeile und das führende Leerzeichen mit einem \; beispielsweise:

let string = "one line \
    written over \
    several";

ist das gleiche wie "one line written over several".

Wenn Sie Zeilenumbrüche in der Zeichenfolge wünschen, können Sie diese vor dem \:

let string = "multiple\n\
              lines\n\
              with\n\
              indentation";

Es ist das gleiche wie "multiple\nlines\nwith\nindentation";

huon
quelle
2
Wenn nur Lesbarkeit das Problem ist, möchte ich das concat!()Makro hinzufügen , um die angegebenen Optionen zu vervollständigen ( doc.rust-lang.org/std/macro.concat.html )
hakononakani
81

Wenn Sie etwas länger arbeiten möchten, einschließlich Anführungszeichen, Backslashes usw., verwenden Sie die Literalnotation für rohe Zeichenfolgen :

let shader = r#"
    #version 330

    in vec4 v_color;
    out vec4 color;

    void main() {
        color = v_color;
    };
"#;

Wenn Ihre Zeichenfolge Folgen von doppelten Anführungszeichen und Hash-Symbolen enthält, können Sie eine beliebige Anzahl von Hashes als Trennzeichen angeben:

let crazy_raw_string = r###"
    My fingers #"
    can#"#t stop "#"" hitting
    hash##"#
"###;
c0g
quelle
Aber ... Sie müssen nur Zeilenumbrüche vermeiden, wenn Sie keine Zeilenumbrüche im Ergebnis haben möchten, und rohe Zeichenfolgen helfen dabei nicht.
Poolie
Rohe Zeichenfolgen verhindern nur, dass Sie am Ende jeder Zeile ein '\' hinzufügen müssen, wenn Sie sich nicht für die Zeilenumbrüche interessieren (z. B. wenn Sie Code einbetten, der wie Shader und Kernel für Zeilenumbrüche agnostisch ist) oder, wie Sie angedeutet haben bis, wenn die Zeilenumbrüche tatsächlich notwendig sind. Es macht es einfach einfacher, Code einzubetten, den Sie möglicherweise bearbeiten möchten, und muss sich nicht mit dem '\' am Ende jeder Zeile herumschlagen. Das ist alles.
c0g
1
Wenn Sie Zeilenumbrüche in der resultierenden Zeichenfolge wünschen (oder nichts dagegen haben), sind einfache Zeichenfolgen in doppelten Anführungszeichen perfekt geeignet, wie in den anderen Beispielen gezeigt. Wenn Sie Zeilenumbrüche vermeiden möchten, sind rohe Zeichenfolgen nicht gut. Sie helfen wirklich nur, wenn der Text Anführungszeichen, Backslashes usw. enthält - wie es in eingebetteten Quellen vorkommen kann.
Poolie
2
Ich sehe, worauf du gerade hinaus willst und du hast absolut Recht.
c0g
1
Es wäre hilfreich, die Ausgabe des Druckens dieser Zeichenfolgen anzuzeigen. Anhand der Antwort selbst kann ich nicht erkennen, was mit Zeilenumbrüchen passieren wird und wie mit Einrückungen umgegangen wird.
bluenote10
46

Huons Antwort ist richtig, aber wenn Sie der Einzug stört, sollten Sie Indoc verwenden , ein prozedurales Makro für eingerückte mehrzeilige Zeichenfolgen. Es steht für "eingerücktes Dokument". Es wird ein Makro namens aufgerufen indoc!(), das ein mehrzeiliges Zeichenfolgenliteral verwendet und die Einrückung aufhebt, sodass sich das Zeichen ganz links, das kein Leerzeichen ist, in der ersten Spalte befindet.

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

Das Ergebnis ist "line one\nline two".

Es gibt einige gleichwertige Möglichkeiten, dasselbe zu formatieren, wenn Sie dies bevorzugen. Wählen Sie also eine aus, die Ihnen gefällt. Die folgenden beiden führen zu derselben Zeichenfolge wie oben. Der Inhalt kann beliebig eingerückt werden - es muss keine bestimmte Anzahl von Leerzeichen sein.

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

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

Das Leerzeichen bleibt relativ zum am weitesten links stehenden Nicht-Leerzeichen im Dokument erhalten, sodass in Zeile 2 drei Leerzeichen relativ zu Zeile 1 eingerückt sind:

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

Das Ergebnis ist "line one\n line two".

dtolnay
quelle
8

Falls Sie mehrzeiligen Text in Ihren Code einrücken möchten:

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

println!("Multiline text goes next:\n{}", s);

Das Ergebnis ist folgendes:

Multiline text goes next:
first line
second line
third line
Igor
quelle
Bitte geben Sie mit Prosa ausdrücklich an , welcher Teil des Codes für dieses Verhalten wichtig ist.
Shepmaster
Im Moment scheint dies der akzeptierten Antwort nichts Neues hinzuzufügen , das besagt: Man kann den \nZeilenumbruch verwenden, [...] man kann den Zeilenumbruch und das führende Leerzeichen mit einem{backslash} . (Es ist sehr schwer, einen Backslash in Code in einen Kommentar
einzugeben
2
Dieser Kommentar schlägt eine Möglichkeit vor, die beiden Punkte in der akzeptierten Antwort zu kombinieren: Wie Sie eine mehrzeilige Zeichenfolge erstellen können, die als mehrzeilige Zeilen im Code geschrieben ist, die aber gleichzeitig - aus stilistischen oder leserlichen Gründen - erhalten darf eine eigene Einrückung im Code, ohne dass diese Einrückung in der letzten Zeichenfolge endet. Es wird im Text nicht sehr deutlich gemacht, aber es ist ein häufiger Anwendungsfall und somit ein wertvoller Vorschlag imho. (Siehe die Antwort von dtolnay für die Kistenversion davon.)
Dato