C 字符串字面量

摘要

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

详情

从 Rust 1.77 版本开始,可以使用带有 ccr 前缀的 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 的警告。有关更多详细信息,请参阅该章节。