C 字符串字面量

总结

  • 形式为 c"foo"cr"foo" 的字面量表示类型为 &core::ffi::CStr 的字符串。

详情

从 Rust 1.77 开始,可以使用带有 ccr 前缀的 C 字符串字面量语法编写 C 字符串。

以前,要生成一个有效的字符串字面量,使其能够与以 NUL 字节结尾的 C API 进行互操作,是一项具有挑战性的任务。cstr crate 是一个流行的解决方案,但它需要编译一个开销相当大的过程宏。现在,可以使用字面量语法符号直接编写 C 字符串,这将生成一个类型为 &core::ffi::CStr 的值,该值会自动以 NUL 字节结尾。

#![allow(unused)]
fn main() {
use core::ffi::CStr;

assert_eq!(c"hello", CStr::from_bytes_with_nul(b"hello\0").unwrap());
assert_eq!(
    c"byte escapes \xff work",
    CStr::from_bytes_with_nul(b"byte escapes \xff work\0").unwrap()
);
assert_eq!(
    c"unicode escapes \u{00E6} work",
    CStr::from_bytes_with_nul(b"unicode escapes \xc3\xa6 work\0").unwrap()
);
assert_eq!(
    c"unicode characters αβγ encoded as UTF-8",
    CStr::from_bytes_with_nul(
        b"unicode characters \xce\xb1\xce\xb2\xce\xb3 encoded as UTF-8\0"
    )
    .unwrap()
);
assert_eq!(
    c"strings can continue \
        on multiple lines",
    CStr::from_bytes_with_nul(b"strings can continue on multiple lines\0").unwrap()
);
}

C 字符串不允许内部出现 NUL 字节(例如使用 \0 转义字符)。

与常规字符串类似,C 字符串也支持带有 cr 前缀的“原始”语法。这些原始 C 字符串不会处理反斜杠转义,这使得编写包含反斜杠的字符串变得更容易。可以通过用 # 字符包围引号来包含双引号。可以使用多个 # 字符来避免与内部 "# 序列产生歧义。

#![allow(unused)]
fn main() {
assert_eq!(cr"foo", c"foo");
// Number signs can be used to embed interior double quotes.
assert_eq!(cr#""foo""#, c"\"foo\"");
// This requires two #.
assert_eq!(cr##""foo"#"##, c"\"foo\"#");
// Escapes are not processed.
assert_eq!(cr"C:\foo", c"C:\\foo");
}

有关更多详细信息,请参阅参考

迁移

只有在宏可能假设存在类似于 c"…"cr"…" 的标记序列时,才需要进行迁移。在 2021 版本之前,这些标记会被标记为两个单独的标记,但在 2021 版本中,它们会显示为单个标记。

作为 2021 版本语法保留的一部分,任何可能遇到此问题的宏输入都应该发出来自 rust_2021_prefixes_incompatible_syntax 迁移 linter 的警告。有关更多详细信息,请参阅该章节。