C 字符串字面量
摘要
- 形如
c"foo"
或cr"foo"
的字面量表示类型为&core::ffi::CStr
的字符串。
详情
从 Rust 1.77 版本开始,可以使用带有 c
或 cr
前缀的 C 字符串字面量语法来编写 C 字符串。
以前,要正确生成一个能与以 NUL 字节结尾的 C API 互操作的有效字符串字面量是具有挑战性的。 cstr
crate 是一个流行的解决方案,但这需要编译一个相当昂贵的 proc-macro。现在,可以使用字面量语法直接编写 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
迁移 lint 的警告。有关更多详细信息,请参阅该章节。