01-字面量表达式
9 分钟阅读
译文 · 基于 The Rust Reference
原文链接: https://doc.rust-lang.org/reference/expressions/literal-expr.html
r[expr.literal]
字面量表达式
r[expr.literal.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`
r[expr.literal.intro] 字面量表达式是由单个 token(而非一串 token)构成的表达式,它立即且直接地指明其求值所得的值,而不是通过名称或其他求值规则来引用该值。
r[expr.literal.const-expr] 字面量是一种常量表达式,因此(主要)在编译期求值。
r[expr.literal.literal-token]
前文所述的每一种词法字面量形式都可以构成字面量表达式,关键字 true 和 false 也可以。
| |
r[expr.literal.string-representation] 在下文的描述中,token 的字符串表示是输入中匹配了该 token 在 Lexer 文法片段中的产生式的那一串字符。
注意 该字符串表示从不包含紧跟着
U+000A(LF)的字符U+000D(CR):这一对会在此前已被转换为单个U+000A(LF)。
r[expr.literal.escape]
转义
r[expr.literal.escape.intro] 下文对文本字面量表达式的描述使用了若干种形式的转义。
r[expr.literal.escape.sequence] 每种转义形式的特征是:
- 一个转义序列:一串字符,总是以
U+005C(\)开始 - 一个转义值:要么是单个字符,要么是空的字符序列
在下文转义的定义中:
- 八进制数字是范围 [
0-7] 中的任意字符。 - 十六进制数字是范围 [
0-9]、[a-f] 或 [A-F] 中的任意字符。
r[expr.literal.escape.simple]
简单转义
下表第一列中出现的每一串字符都是转义序列。
在每种情况下,转义值都是第二列对应条目中给出的字符。
| 转义序列 | 转义值 |
|---|---|
\0 | U+0000 (NUL) |
\t | U+0009 (HT) |
\n | U+000A (LF) |
\r | U+000D (CR) |
\" | U+0022 (QUOTATION MARK) |
\' | U+0027 (APOSTROPHE) |
\\ | U+005C (REVERSE SOLIDUS) |
r[expr.literal.escape.hex-octet]
8 位转义
转义序列由 \x 后跟两位十六进制数字组成。
转义值是这样一个字符:其Unicode 标量值等于把转义序列的最后两个字符按十六进制整数来解释的结果,如同使用进制为 16 的 [u8::from_str_radix]。
注意 因此,转义值的Unicode 标量值落在
u8的范围内。
r[expr.literal.escape.hex-ascii]
7 位转义
转义序列由 \x 后跟一位八进制数字再跟一位十六进制数字组成。
转义值是这样一个字符:其Unicode 标量值等于把转义序列的最后两个字符按十六进制整数来解释的结果,如同使用进制为 16 的 [u8::from_str_radix]。
r[expr.literal.escape.unicode]
Unicode 转义
转义序列由 \u{、随后一串每个都是十六进制数字或 _ 的字符、再随后 } 组成。
转义值是这样一个字符:其Unicode 标量值等于把转义序列中所含的十六进制数字按十六进制整数来解释的结果,如同使用进制为 16 的 [u32::from_str_radix]。
注意 [CHAR_LITERAL] 或 [STRING_LITERAL] token 的合法形式确保存在这样的字符。
r[expr.literal.continuation]
字符串续行转义
转义序列由紧跟着 U+000A(LF)的 \,以及下一个非空白字符之前的所有后续空白字符组成。就此而言,空白字符为 U+0009(HT)、U+000A(LF)、U+000D(CR)和 U+0020(SPACE)。
转义值是空的字符序列。
注意 这种转义的效果是字符串续行会跳过后续空白,包括额外的换行。因此
a、b和c相等:
1 2 3 4 5 6 7 8 9let a = "foobar"; let b = "foo\ bar"; let c = "foo\ bar"; assert_eq!(a, b); assert_eq!(b, c);跳过额外的换行(如示例 c)可能令人困惑且出人意料。此行为将来可能会调整。在做出决定之前,建议不要依赖用续行来跳过多个换行。更多信息见此 issue。
r[expr.literal.char]
字符字面量表达式
r[expr.literal.char.intro] 字符字面量表达式由单个 [CHAR_LITERAL] token 组成。
r[expr.literal.char.type]
该表达式的类型是原始 char 类型。
r[expr.literal.char.no-suffix] 该 token 不得带有后缀。
r[expr.literal.char.literal-content]
该 token 的字面内容是其字符串表示中第一个 U+0027(')之后、最后一个 U+0027(')之前的字符序列。
r[expr.literal.char.represented] 字面量表达式的所表示字符由字面内容按如下方式导出:
r[expr.literal.char.escape]
- 若字面内容是下列形式的转义序列之一,则所表示字符就是该转义序列的转义值:
r[expr.literal.char.single]
- 否则,所表示字符就是构成字面内容的那个单个字符。
r[expr.literal.char.result]
该表达式的值是与所表示字符的Unicode 标量值相对应的 char。
注意 [CHAR_LITERAL] token 的合法形式确保这些规则总是产生单个字符。
字符字面量表达式的示例:
| |
r[expr.literal.string]
字符串字面量表达式
r[expr.literal.string.intro] 字符串字面量表达式由单个 [STRING_LITERAL] 或 [RAW_STRING_LITERAL] token 组成。
r[expr.literal.string.type]
该表达式的类型是指向原始 str 类型的共享引用(生命周期为 static)。亦即类型为 &'static str。
r[expr.literal.string.no-suffix] 该 token 不得带有后缀。
r[expr.literal.string.literal-content]
该 token 的字面内容是其字符串表示中第一个 U+0022(")之后、最后一个 U+0022(")之前的字符序列。
r[expr.literal.string.represented] 字面量表达式的所表示字符串是由字面内容按如下方式导出的字符序列:
r[expr.literal.string.escape]
若该 token 是 [STRING_LITERAL],则字面内容中出现的下列任何形式的每个转义序列,都会被替换为该转义序列的转义值。
这些替换按从左到右的顺序进行。例如,token
"\\x41"被转换为字符\x41。
r[expr.literal.string.raw]
- 若该 token 是 [RAW_STRING_LITERAL],则所表示字符串与字面内容相同。
r[expr.literal.string.result]
该表达式的值是对静态分配的 str 的引用,其中包含所表示字符串的 UTF-8 编码。
字符串字面量表达式的示例:
| |
r[expr.literal.byte-char]
字节字面量表达式
r[expr.literal.byte-char.intro] 字节字面量表达式由单个 [BYTE_LITERAL] token 组成。
r[expr.literal.byte-char.literal]
该表达式的类型是原始 u8 类型。
r[expr.literal.byte-char.no-suffix] 该 token 不得带有后缀。
r[expr.literal.byte-char.literal-content]
该 token 的字面内容是其字符串表示中第一个 U+0027(')之后、最后一个 U+0027(')之前的字符序列。
r[expr.literal.byte-char.represented] 字面量表达式的所表示字符由字面内容按如下方式导出:
r[expr.literal.byte-char.escape]
r[expr.literal.byte-char.single]
- 否则,所表示字符就是构成字面内容的那个单个字符。
r[expr.literal.byte-char.result] 该表达式的值是所表示字符的Unicode 标量值。
注意 [BYTE_LITERAL] token 的合法形式确保这些规则总是产生单个字符,且其 Unicode 标量值落在
u8的范围内。
字节字面量表达式的示例:
| |
r[expr.literal.byte-string]
字节字符串字面量表达式
r[expr.literal.byte-string.intro] 字节字符串字面量表达式由单个 [BYTE_STRING_LITERAL] 或 [RAW_BYTE_STRING_LITERAL] token 组成。
r[expr.literal.byte-string.type]
该表达式的类型是指向元素类型为 u8 的数组的共享引用(生命周期为 static)。亦即类型为 &'static [u8; N],其中 N 是下文所述所表示字符串中的字节数。
r[expr.literal.byte-string.no-suffix] 该 token 不得带有后缀。
r[expr.literal.byte-string.literal-content]
该 token 的字面内容是其字符串表示中第一个 U+0022(")之后、最后一个 U+0022(")之前的字符序列。
r[expr.literal.byte-string.represented] 字面量表达式的所表示字符串是由字面内容按如下方式导出的字符序列:
r[expr.literal.byte-string.escape]
若该 token 是 [BYTE_STRING_LITERAL],则字面内容中出现的下列任何形式的每个转义序列,都会被替换为该转义序列的转义值。
这些替换按从左到右的顺序进行。例如,token
b"\\x41"被转换为字符\x41。
r[expr.literal.byte-string.raw]
- 若该 token 是 [RAW_BYTE_STRING_LITERAL],则所表示字符串与字面内容相同。
r[expr.literal.byte-string.result] 该表达式的值是对静态分配数组的引用,该数组按相同顺序包含所表示字符串中各字符的Unicode 标量值。
注意 [BYTE_STRING_LITERAL] 和 [RAW_BYTE_STRING_LITERAL] token 的合法形式确保这些规则总是产生落在
u8范围内的数组元素值。
字节字符串字面量表达式的示例:
| |
r[expr.literal.c-string]
C 字符串字面量表达式
r[expr.literal.c-string.intro] C 字符串字面量表达式由单个 [C_STRING_LITERAL] 或 [RAW_C_STRING_LITERAL] token 组成。
r[expr.literal.c-string.type]
该表达式的类型是指向标准库 CStr 类型的共享引用(生命周期为 static)。亦即类型为 &'static core::ffi::CStr。
r[expr.literal.c-string.no-suffix] 该 token 不得带有后缀。
r[expr.literal.c-string.literal-content]
该 token 的字面内容是其字符串表示中第一个 " 之后、最后一个 " 之前的字符序列。
r[expr.literal.c-string.represented] 字面量表达式的所表示字节是由字面内容按如下方式导出的字节序列:
r[expr.literal.c-string.escape]
- 若该 token 是 [C_STRING_LITERAL],则字面内容被视为一个项序列,其中每一项要么是除
\之外的单个 Unicode 字符,要么是一次转义。该项序列按如下方式转换为字节序列:- 每个单独的 Unicode 字符贡献其 UTF-8 表示。
- 每次简单转义贡献其转义值的Unicode 标量值。
- 每次8 位转义贡献一个包含其转义值之Unicode 标量值的单字节。
- 每次Unicode 转义贡献其转义值的 UTF-8 表示。
- 每次字符串续行转义不贡献任何字节。
r[expr.literal.c-string.raw]
- 若该 token 是 [RAW_C_STRING_LITERAL],则所表示字节是字面内容的 UTF-8 编码。
注意 [C_STRING_LITERAL] 和 [RAW_C_STRING_LITERAL] token 的合法形式确保所表示字节从不包含空字节。
r[expr.literal.c-string.result] 该表达式的值是对静态分配的 CStr 的引用,其字节数组包含所表示字节后跟一个空字节。
C 字符串字面量表达式的示例:
| |
r[expr.literal.int]
整数字面量表达式
r[expr.literal.int.intro] 整数字面量表达式由单个 [INTEGER_LITERAL] token 组成。
r[expr.literal.int.suffix]
若该 token 带有后缀,则后缀必须是原始整数类型之一的名称:u8、i8、u16、i16、u32、i32、u64、i64、u128、i128、usize 或 isize,且该表达式具有该类型。
r[expr.literal.int.infer] 若该 token 没有后缀,则该表达式的类型由类型推断确定:
r[expr.literal.int.inference-unique-type]
- 若可以从周围的程序上下文中唯一确定一个整数类型,则该表达式具有该类型。
r[expr.literal.int.inference-default]
- 若程序上下文对该类型约束不足,则默认采用有符号 32 位整数
i32。
r[expr.literal.int.inference-error]
- 若程序上下文对该类型约束过度,则视为静态类型错误。
整数字面量表达式的示例:
| |
r[expr.literal.int.representation] 该表达式的值由该 token 的字符串表示按如下方式确定:
r[expr.literal.int.radix]
通过检查该字符串的前两个字符来选择整数进制,如下:
0b表示进制 20o表示进制 80x表示进制 16- 否则进制为 10。
r[expr.literal.int.radix-prefix-stripped]
- 若进制不是 10,则从该字符串中移除前两个字符。
r[expr.literal.int.type-suffix-stripped]
- 从该字符串中移除任何后缀。
r[expr.literal.int.separators-stripped]
- 从该字符串中移除所有下划线。
r[expr.literal.int.u128-value]
- 将该字符串按所选进制转换为
u128值,如同使用 [u128::from_str_radix]。若该值无法放入u128,则为编译器错误。
r[expr.literal.int.cast]
- 该
u128值通过数值转换转换为该表达式的类型。
注意 若字面量的值无法放入该表达式的类型,最终的转换会截断该值。
rustc包含一个名为overflowing_literals的lint 检查,默认级别为deny,会拒绝发生这种情况的表达式。
注意 例如,
-1i8是对字面量表达式1i8应用取负运算符,而不是单个整数字面量表达式。关于如何表示有符号类型的最小负值,见溢出。
r[expr.literal.float]
浮点字面量表达式
r[expr.literal.float.intro] 浮点字面量表达式有两种形式之一:
- 单个 [FLOAT_LITERAL] token
- 单个带有后缀且没有进制指示的 [INTEGER_LITERAL] token
r[expr.literal.float.suffix]
若该 token 带有后缀,则后缀必须是原始浮点类型之一的名称:f32 或 f64,且该表达式具有该类型。
r[expr.literal.float.infer] 若该 token 没有后缀,则该表达式的类型由类型推断确定:
r[expr.literal.float.inference-unique-type]
- 若可以从周围的程序上下文中唯一确定一个浮点类型,则该表达式具有该类型。
r[expr.literal.float.inference-default]
- 若程序上下文对该类型约束不足,则默认为
f64。
r[expr.literal.float.inference-error]
- 若程序上下文对该类型约束过度,则视为静态类型错误。
浮点字面量表达式的示例:
| |
r[expr.literal.float.result] 该表达式的值由该 token 的字符串表示按如下方式确定:
r[expr.literal.float.type-suffix-stripped]
- 从该字符串中移除任何后缀。
r[expr.literal.float.separators-stripped]
- 从该字符串中移除所有下划线。
r[expr.literal.float.value]
- 将该字符串转换为该表达式的类型,如同使用
f32::from_str或f64::from_str。
注意 例如,
-1.0是对字面量表达式1.0应用取负运算符,而不是单个浮点字面量表达式。
注意
inf和NaN不是字面量 token。可以使用 [f32::INFINITY]、[f64::INFINITY]、[f32::NAN] 和 [f64::NAN] 常量来代替字面量表达式。在rustc中,大到会被求值为无穷大的字面量会触发overflowing_literalslint 检查。
r[expr.literal.bool]
布尔字面量表达式
r[expr.literal.bool.intro]
布尔字面量表达式由关键字 true 或 false 之一组成。
r[expr.literal.bool.result] 该表达式的类型是原始布尔类型,其值为:
- 关键字为
true时为 true - 关键字为
false时为 false