Rust
中的三大【原始raw
】项
引言
我早先写过一篇【聊rust
中三大条件处理】的文章。最近梳理代码,我又偶然发现另一组“三大”。即,三大·原始raw
项。它们包括:
- 原始·字符串·字面量
Raw String Literal
- 对应于:字符串·字面量
String Literal
- 对应于:字符串·字面量
- 原始·字节·字符串·字面量
Raw Byte String Literal
- 对应于:字节·字符串·字面量
Byte String Literal
- 对应于:字节·字符串·字面量
- 原始·识别符
Raw Identifier
- 馁馁的孤例,没有对应了。
这三“大”项Items
的概念并不复杂。我就是感觉·这接连出现的两组“三大”挺有意思。所以,和大家分享一下。此外,我也不确定是否还会遇见第三组与第四组...
概述
- 首先,前两项(
Raw String Literal
和Raw Byte String Literal
)的共同特点是:批量转义·字符串·字面量·内的特殊字符”。从而,避免充斥着许多转义符的大段字符串,和提高代码的可读性。或许,将这两项·类比为
ECMAScript 6
中的【模板·字符串】撇号语法会更容易理解些(它们的主要功能极为接近)。 - 其次,
Raw Byte String Literal
就是<原始 ASCII 字符串·字面量>.as_bytes()
的语法糖 [例程1]。展开来讲,- 【原始·字节·字符串·字面量】仅只接受
ASCII
字符作为内容,因为它要·以从char
至byte
一一对应的方式·将字符串转变成&[u8]
。 - 千万别被它名字内的
String
给误导了,【原始·字节·字符串·字面量】是不认识UTF-8
编码格式的,更不一定是有效的UTF-8
字节序列。因此,可别惦记“汉字”字面量呀!
- 【原始·字节·字符串·字面量】仅只接受
- 最后,
Raw Identifier
是为了兼容性而生,和什么转义可没有半毛钱关系。具体地讲,它允许·依托于最新版次rustc
的Cargo Package
工程导入满足以下特点的“老古董”crate
作为依赖项:- 仅能由低版次
rustc
编译器成功。比如,rust toolchain 2015
。 - 其导出的
pub
函数或变量名·与·新版次rustc
引入的保留·关键字·相冲突。比如,来自rust 2018
的try
关键字。
- 仅能由低版次
原始·字符串·字面量Raw String Literal
- 相对于【字符串·字面量
String Literal
】,Raw String Literal
仅能转义【换行符】与【缩进】[例程2]。而String Literal
还能转义- 以
x
为前缀的·代表任意字符的·十六进制数字 [例程3] - 匹配
u{十六进制数字}
格式的·代表任意字符的·Unicode
码 [例程4]
- 以
- 标识
Raw String Literal
套路就是:左右两侧的#
符可以被无限增加下去,直至由多个#
与单个"
构成的字符组合不会出现于字符串字面量里为止。r"<没有包含·双引号·的字符串>"
r#"<包含了
", 但没有包含
#"和
"#的字符串>"#
r##"<包含了
#"或
"#,但没有包含
##"和
"##的字符串>"##
r###"<包含了
##"或
"##,但没有包含
###"和
"###的字符串>"###
原始·字节·字符串·字面量Raw Byte String Literal
- 相对于【字节·字符串·字面量
Byte String Literal
】,Raw Byte String Literal
仅能转义【换行符】与【缩进】[例程5]。而Byte String Literal
还能转义- 以
x
为前缀的·代表任意字符的·十六进制数字 [例程6]
- 以
- 标识
Raw Byte String Literal
套路就是:左右两侧的#
符可以被无限增加下去,直至由多个#
与单个"
构成的字符组合不会出现于字符串字面量里为止。br"<没有包含·双引号·的字符串>"
br#"<包含了
", 但没有包含
#"和
"#的字符串>"#
br##"<包含了
#"或
"#,但没有包含
##"和
"##的字符串>"##
br###"<包含了
##"或
"##,但没有包含
###"和
"###的字符串>"###
原始·识别符Raw Identifier
- 馁馁的孤例,没有可做对比的。
- 标识
Raw Identifier
r#<Identifier>
- 一个用例,请重点看代码注释。 extern crate foo; // 只有`rustc 2015`才能成功编译依赖项`foo crate`fn main() { // `Cargo Package`采用的编译环境是`rustc 2021` foo::r#try(); // `foo crate`的导出函数`foo::try()`名与`rustc 2018`的新关键字`try`冲突了。}
结束语
这次要分享的就是这些。其实,我对【原始·字符串·字面量】的使用率还是比较高,但对其它两项也就蹭了个概念熟。