Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Выражения-литералы

Syntax
LiteralExpression
      CHAR_LITERAL
    | STRING_LITERAL
    | RAW_STRING_LITERAL
    | BYTE_LITERAL
    | BYTE_STRING_LITERAL
    | RAW_BYTE_STRING_LITERAL
    | C_STRING_LITERAL
    | RAW_C_STRING_LITERAL
    | INTEGER_LITERAL
    | FLOAT_LITERAL
    | true
    | false

Выражение-литерал — это выражение, состоящее из одного токена, а не из последовательности токенов, которое непосредственно и прямо обозначает значение, к которому оно вычисляется, а не ссылается на него по имени или по какому-либо другому правилу вычисления.

Литерал является формой константного выражения, поэтому вычисляется (в основном) во время компиляции.

Каждая из лексических форм литеральных токенов, описанных ранее, может составлять выражение-литерал, как и ключевые слова true и false.

#![allow(unused)]
fn main() {
"hello";   // строковый тип
'5';       // символьный тип
5;         // целочисленный тип
}

В приведенных ниже описаниях строковое представление токена — это последовательность символов из входных данных, которая соответствует продукции токена в грамматике Лексера.

Note

Это строковое представление никогда не включает символ U+000D (CR), за которым сразу следует U+000A (LF): эта пара была бы ранее преобразована в один U+000A (LF).

Экранирования

В описаниях текстовых выражений-литералов ниже используются несколько форм экранирования.

Каждая форма экранирования характеризуется:

  • последовательностью экранирования: последовательностью символов, которая всегда начинается с U+005C (\)
  • экранированным значением: либо одним символом, либо пустой последовательностью символов

В определениях экранирований ниже:

  • Восьмеричная цифра — это любой из символов в диапазоне [0-7].
  • Шестнадцатеричная цифра — это любой из символов в диапазонах [0-9], [a-f] или [A-F].

Простые экранирования

Каждая последовательность символов, встречающаяся в первом столбце следующей таблицы, является последовательностью экранирования.

В каждом случае экранированное значение — это символ, указанный в соответствующей записи во втором столбце.

ПоследовательностьЭкранированное значение
\0U+0000 (NUL)
\tU+0009 (HT)
\nU+000A (LF)
\rU+000D (CR)
\"U+0022 (КАВЫЧКА)
\'U+0027 (АПОСТРОФ)
\\U+005C (ОБРАТНАЯ КОСАЯ ЧЕРТА)

8-битные экранирования

Последовательность экранирования состоит из \x, за которым следуют две шестнадцатеричные цифры.

Экранированное значение — это символ, скалярное значение Юникода которого является результатом интерпретации последних двух символов в последовательности экранирования как шестнадцатеричного целого числа, как если бы с помощью u8::from_str_radix с основанием 16.

Note

Таким образом, экранированное значение имеет скалярное значение Юникода в диапазоне u8.

7-битные экранирования

Последовательность экранирования состоит из \x, за которым следуют восьмеричная цифра, а затем шестнадцатеричная цифра.

Экранированное значение — это символ, скалярное значение Юникода которого является результатом интерпретации последних двух символов в последовательности экранирования как шестнадцатеричного целого числа, как если бы с помощью u8::from_str_radix с основанием 16.

Юникодные экранирования

Последовательность экранирования состоит из \u{, за которым следует последовательность символов, каждый из которых является шестнадцатеричной цифрой или _, а затем }.

Экранированное значение — это символ, скалярное значение Юникода которого является результатом интерпретации шестнадцатеричных цифр, содержащихся в последовательности экранирования, как шестнадцатеричного целого числа, как если бы с помощью u32::from_str_radix с основанием 16.

Note

Разрешенные формы токенов CHAR_LITERAL или STRING_LITERAL гарантируют, что такой символ существует.

Экранирования продолжения строки

Последовательность экранирования состоит из \, за которым сразу следует U+000A (LF), и всех последующих пробельных символов до следующего непробельного символа. Для этой цели пробельными символами являются U+0009 (HT), U+000A (LF), U+000D (CR) и U+0020 (SPACE).

Экранированное значение представляет собой пустую последовательность символов.

Note

Эффект этой формы экранирования заключается в том, что продолжение строки пропускает последующие пробелы, включая дополнительные переводы строк. Таким образом, a, b и c равны:

#![allow(unused)]
fn main() {
let a = "foobar";
let b = "foo\
         bar";
let c = "foo\

     bar";

assert_eq!(a, b);
assert_eq!(b, c);
}

Пропуск дополнительных переводов строк (как в примере c) потенциально сбивает с толку и является неожиданным. Это поведение может быть изменено в будущем. Пока решение не принято, рекомендуется избегать зависимости от пропуска нескольких переводов строк с помощью продолжений строк. Дополнительную информацию смотрите в этом issue.

Символьные выражения-литералы

Символьное выражение-литерал состоит из одного токена CHAR_LITERAL.

Тип выражения — примитивный тип char.

Токен не должен иметь суффикса.

Содержимое литерала токена — это последовательность символов, следующая за первым U+0027 (') и предшествующая последнему U+0027 (') в строковом представлении токена.

Представленный символ выражения-литерала получается из содержимого литерала следующим образом:

  • В противном случае представленный символ — это единственный символ, составляющий содержимое литерала.

Значением выражения является char, соответствующий скалярному значению Юникода представленного символа.

Note

Разрешенные формы токена CHAR_LITERAL гарантируют, что эти правила всегда производят один символ.

Примеры символьных выражений-литералов:

#![allow(unused)]
fn main() {
'R';                               // R
'\'';                              // '
'\x52';                            // R
'\u{00E6}';                        // LATIN SMALL LETTER AE (U+00E6)
}

Строковые выражения-литералы

Строковое выражение-литерал состоит из одного токена STRING_LITERAL или RAW_STRING_LITERAL.

Тип выражения — разделяемая ссылка (со временем жизни static) на примитивный тип str. То есть тип — &'static str.

Токен не должен иметь суффикса.

Содержимое литерала токена — это последовательность символов, следующая за первым U+0022 (") и предшествующая последнему U+0022 (") в строковом представлении токена.

Представленная строка выражения-литерала — это последовательность символов, полученная из содержимого литерала следующим образом:

  • Если токен является RAW_STRING_LITERAL, представленная строка идентична содержимому литерала.

Значением выражения является ссылка на статически выделенный str, содержащий UTF-8 кодировку представленной строки.

Примеры строковых выражений-литералов:

#![allow(unused)]
fn main() {
"foo"; r"foo";                     // foo
"\"foo\""; r#""foo""#;             // "foo"

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

"\x52"; "R"; r"R";                 // R
"\\x52"; r"\x52";                  // \x52
}

Байтовые выражения-литералы

Байтовое выражение-литерал состоит из одного токена BYTE_LITERAL.

Тип выражения — примитивный тип u8.

Токен не должен иметь суффикса.

Содержимое литерала токена — это последовательность символов, следующая за первым U+0027 (') и предшествующая последнему U+0027 (') в строковом представлении токена.

Представленный символ выражения-литерала получается из содержимого литерала следующим образом:

  • Если содержимое литерала является одной из следующих форм последовательности экранирования, то представленный символ — это экранированное значение последовательности экранирования:
  • В противном случае представленный символ — это единственный символ, составляющий содержимое литерала.

Значением выражения является скалярное значение Юникода представленного символа.

Note

Разрешенные формы токена BYTE_LITERAL гарантируют, что эти правила всегда производят один символ, чье скалярное значение Юникода находится в диапазоне u8.

Примеры байтовых выражений-литералов:

#![allow(unused)]
fn main() {
b'R';                              // 82
b'\'';                             // 39
b'\x52';                           // 82
b'\xA0';                           // 160
}

Байтовые строковые выражения-литералы

Байтовое строковое выражение-литерал состоит из одного токена BYTE_STRING_LITERAL или RAW_BYTE_STRING_LITERAL.

Тип выражения — разделяемая ссылка (со временем жизни static) на массив, тип элемента которого — u8. То есть тип — &'static [u8; N], где N — количество байт в представленной строке, описанной ниже.

Токен не должен иметь суффикса.

Содержимое литерала токена — это последовательность символов, следующая за первым U+0022 (") и предшествующая последнему U+0022 (") в строковом представлении токена.

Представленная строка выражения-литерала — это последовательность символов, полученная из содержимого литерала следующим образом:

  • Если токен является RAW_BYTE_STRING_LITERAL, представленная строка идентична содержимому литерала.

Значением выражения является ссылка на статически выделенный массив, содержащий скалярные значения Юникода символов в представленной строке, в том же порядке.

Note

Разрешенные формы токенов BYTE_STRING_LITERAL и RAW_BYTE_STRING_LITERAL гарантируют, что эти правила всегда производят значения элементов массива в диапазоне u8.

Примеры байтовых строковых выражений-литералов:

#![allow(unused)]
fn main() {
b"foo"; br"foo";                     // foo
b"\"foo\""; br#""foo""#;             // "foo"

b"foo #\"# bar";
br##"foo #"# bar"##;                 // foo #"# bar

b"\x52"; b"R"; br"R";                // R
b"\\x52"; br"\x52";                  // \x52
}

Строковые выражения-литералы в стиле C

Строковое выражение-литерал в стиле C состоит из одного токена C_STRING_LITERAL или RAW_C_STRING_LITERAL.

Тип выражения — разделяемая ссылка (со временем жизни static) на тип CStr из стандартной библиотеки. То есть тип — &'static core::ffi::CStr.

Токен не должен иметь суффикса.

Содержимое литерала токена — это последовательность символов, следующая за первым " и предшествующая последнему " в строковом представлении токена.

Представленные байты выражения-литерала — это последовательность байтов, полученная из содержимого литерала следующим образом:

  • Если токен является RAW_C_STRING_LITERAL, представленные байты — это UTF-8 кодировка содержимого литерала.

Note

Разрешенные формы токенов C_STRING_LITERAL и RAW_C_STRING_LITERAL гарантируют, что представленные байты никогда не включают нулевой байт.

Значением выражения является ссылка на статически выделенный CStr, чей массив байтов содержит представленные байты, за которыми следует нулевой байт.

Примеры строковых выражений-литералов в стиле C:

#![allow(unused)]
fn main() {
c"foo"; cr"foo";                     // foo
c"\"foo\""; cr#""foo""#;             // "foo"

c"foo #\"# bar";
cr##"foo #"# bar"##;                 // foo #"# bar

c"\x52"; c"R"; cr"R";                // R
c"\\x52"; cr"\x52";                  // \x52

c"æ";                                // LATIN SMALL LETTER AE (U+00E6)
c"\u{00E6}";                         // LATIN SMALL LETTER AE (U+00E6)
c"\xC3\xA6";                         // LATIN SMALL LETTER AE (U+00E6)

c"\xE6".to_bytes();                  // [230]
c"\u{00E6}".to_bytes();              // [195, 166]
}

Целочисленные выражения-литералы

Целочисленное выражение-литерал состоит из одного токена INTEGER_LITERAL.

Если токен имеет суффикс, этот суффикс должен быть именем одного из примитивных целочисленных типов: u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize или isize, и выражение имеет этот тип.

Если токен не имеет суффикса, тип выражения определяется выводом типа:

  • Если целочисленный тип может быть однозначно определен из окружающего контекста программы, выражение имеет этот тип.
  • Если контекст программы недостаточно ограничивает тип, по умолчанию используется знаковый 32-битный целочисленный тип i32.
  • Если контекст программы чрезмерно ограничивает тип, это считается статической ошибкой типа.

Примеры целочисленных выражений-литералов:

#![allow(unused)]
fn main() {
123;                               // тип i32
123i32;                            // тип i32
123u32;                            // тип u32
123_u32;                           // тип u32
let a: u64 = 123;                  // тип u64

0xff;                              // тип i32
0xff_u8;                           // тип u8

0o70;                              // тип i32
0o70_i16;                          // тип i16

0b1111_1111_1001_0000;             // тип i32
0b1111_1111_1001_0000i64;          // тип i64

0usize;                            // тип usize
}

Значение выражения определяется из строкового представления токена следующим образом:

  • Выбирается целочисленное основание системы счисления путем проверки первых двух символов строки, следующим образом:

    • 0b указывает основание 2
    • 0o указывает основание 8
    • 0x указывает основание 16
    • в противном случае основание равно 10.
  • Если основание не 10, первые два символа удаляются из строки.
  • Любой суффикс удаляется из строки.
  • Любые подчеркивания удаляются из строки.
  • Строка преобразуется в значение u128 как если бы с помощью u128::from_str_radix с выбранным основанием. Если значение не помещается в u128, это ошибка компилятора.

Note

Финальное приведение будет усекать значение литерала, если оно не помещается в тип выражения. rustc включает проверку переполнения литералов с именем overflowing_literals, по умолчанию deny, которая отклоняет выражения, где это происходит.

Note

-1i8, например, это применение оператора отрицания к выражению-литералу 1i8, а не одиночное целочисленное выражение-литерал. См. Переполнение для примечаний о представлении наименьшего отрицательного значения для знакового типа.

Выражения-литералы с плавающей точкой

Выражение-литерал с плавающей точкой имеет одну из двух форм:

  • одиночный токен FLOAT_LITERAL
  • одиночный токен INTEGER_LITERAL, который имеет суффикс и не имеет индикатора системы счисления

Если токен имеет суффикс, этот суффикс должен быть именем одного из примитивных типов с плавающей точкой: f32 или f64, и выражение имеет этот тип.

Если токен не имеет суффикса, тип выражения определяется выводом типа:

  • Если тип с плавающей точкой может быть однозначно определен из окружающего контекста программы, выражение имеет этот тип.
  • Если контекст программы недостаточно ограничивает тип, по умолчанию используется f64.
  • Если контекст программы чрезмерно ограничивает тип, это считается статической ошибкой типа.

Примеры выражений-литералов с плавающей точкой:

#![allow(unused)]
fn main() {
123.0f64;        // тип f64
0.1f64;          // тип f64
0.1f32;          // тип f32
12E+99_f64;      // тип f64
5f32;            // тип f32
let x: f64 = 2.; // тип f64
}

Значение выражения определяется из строкового представления токена следующим образом:

  • Любой суффикс удаляется из строки.
  • Любые подчеркивания удаляются из строки.
  • Строка преобразуется в тип выражения как если бы с помощью f32::from_str или f64::from_str.

Note

-1.0, например, это применение оператора отрицания к выражению-литералу 1.0, а не одиночное выражение-литерал с плавающей точкой.

Note

inf и NaN не являются литеральными токенами. Вместо выражений-литералов можно использовать константы f32::INFINITY, f64::INFINITY, f32::NAN и f64::NAN. В rustc литерал, достаточно большой, чтобы быть оцененным как бесконечность, вызовет проверку переполнения литералов overflowing_literals.

Логические выражения-литералы

Логическое выражение-литерал состоит из одного из ключевых слов true или false.

Тип выражения — примитивный логический тип, и его значение:

  • true, если ключевое слово true
  • false, если ключевое слово false