6.5 其他字符串类型
虽然字符串数据类型是迄今为止最常见、最常用的字符串表示类型,但 Object Pascal 桌面编译器过去和现在都有多种字符串类型。其中一些类型还可用于移动应用程序,在移动应用程序中,您也可以直接使用 TBytes 来操作单字节表示的字符串,如上一节中描述的示例。
过去使用 Object Pascal 的开发人员可能会有很多基于这些前 Unicode 类型(或直接管理 UTF-8)的代码,但现代应用程序需要完整的 Unicode 支持。此外,虽然有些类型(如 UTF8String)在语言中可用,但它们在 RTL 方面的支持是有限的。建议使用普通的标准 Unicode 字符串。
注解:关于 Object Pascal 移动编译器中缺少 AnsiString 和 UTF8String 等本地类型,已经有很多讨论和批评。在 Delphi 10.1 Berlin 中,UTF8String 类型和低级的 RawByteString 类型被正式重新引入,随后的 Delphi 10.4 也在移动设备上启用了所有桌面字符串类型。值得注意的是,几乎没有其他编程语言拥有一种以上的本地或内置字符串类型。掌握多个字符串类型会更加复杂,可能会产生不必要的副作用(如大量的自动转换调用会降低程序的运行速度),而且维护多个版本的字符串管理和处理函数的成本也很高。因此,除个别情况外,建议将重点放在标准字符串类型或 UnicodeString 上。
6.5.1 UCS4String类型
UCS4String 类型是一种有趣但很少使用的字符串类型,所有编译器都支持这种类型。它只是字符串的 UTF-32 表示法,不过是 UTF32Char 元素或 4 字节字符的数组。如前所述,使用这种类型的原因是它可以直接表示所有 Unicode 码点。显而易见的缺点是,这种字符串占用的内存是 UTF-16 字符串的两倍(UTF-16 字符串占用的内存已经是 ANSI 字符串的两倍)。
虽然这种数据类型可以在特定情况下使用,但并不特别适合一般情况。此外,这种类型不支持写时复制,也没有任何真正的系统函数和程序来处理它。
注解:UCS4String 保证每个 Unicode 码点有一个 UTF32Char,但不能保证每个字形或 "可视字符 "有一个 UTF32Char。
6.5.2 旧字符串类型
如前所述,Object Pascal编译器支持一些较旧的传统字符串类型(这些类型从Delphi 10.4开始在所有目标平台上可用)。这些旧字符串类型包括:
- ShortString类型,对应于原始Pascal语言的字符串类型。这些字符串限制为255个字符,每个字符都是ANSIChar类型。
- ANSIString类型,对应于长度可变的字符串。这些字符串采用动态分配、引用计数和写时复制技术。这些字符串的大小几乎不受限制(最多可存储 20 亿个字符!)而且,这种字符串类型基于 ANSIChar 类型,可用于移动编译器,即使 ANSI 表示法是 Windows 特有的,而且某些特殊字符可能会根据平台的不同而有不同的处理方式。
- WideString 类型在表示法上类似于 2 字节 Unicode 字符串,它基于 Char 类型,但与标准字符串类型不同的是,它不使用写时复制(copy-on-write),而且内存分配效率较低。如果你想知道为什么要把它添加到语言中,原因是为了与微软 COM 架构中的字符串管理兼容。
- UTF8String 是基于可变字符长度 UTF-8 格式的字符串。如前所述,运行库对这种类型的支持很少。
- RawByteString是一个没有设置编码页的字符数组,系统不会对其进行字符转换(因此在逻辑上类似于 TBytes 结构,但允许进行一些直接的字符串操作,而字节数组目前还不具备这种功能)。这种数据类型很少在系统库外使用。
- 字符串构造机制允许你定义与特定 ISO 编码页相关联的 1 字节字符串,这是前 Unicode 时代的产物。
再次强调,所有这些字符串类型都可以在桌面编译器上使用,但仅出于向后兼容的原因而提供。目标是在可能的情况下使用Unicode、TEncoding和其他现代字符串管理技术。