什么时候可以安全地将 UnicodeString 转换为 Free Pascal 3 中的字符串?
When is it safe to cast UnicodeString to string in Free Pascal 3?
此单元测试在 Delphi 模式下使用 Free Pascal 3.0 成功运行:
procedure TFreePascalTests.TestUTF8Decode;
var
Raw: RawByteString;
Actual: string;
begin
Raw := UTF8Encode('关于汉语');
Actual := string( UTF8Decode(Raw) ); // <--- cast from UnicodeString
CheckEquals('关于汉语', Actual);
// check Windows ANSI code page
CheckEquals(1252, GetACP);
// check Free Pascal value (determines how CP_ACP is interpreted)
CheckEquals(65001, DefaultSystemCodePage);
end;
UTF8Decode returns 一个 UnicodeString。如果没有将硬类型转换为字符串,编译器会警告不安全的转换:
Warning: Implicit string type conversion with potential data loss from
"UnicodeString" to "AnsiString"
(使用 Lazarus 1.6 / FPCUnit GUITestrunner 测试)
根据http://wiki.freepascal.org/Character_and_string_types#String,字符串类型默认为 AnsiString(如果 {$H+} 开关设置为使用 AnsiString 而不是 ShortString)。
看起来 Free Pascal 将 Unicode 字符串存储在 AnsiString 变量中。 (即使没有演员,测试成功)
问题:随着测试的成功,我是否可以假设使用强制转换(以抑制警告)是安全的而不会有数据丢失的风险?
转换通常不安全,因为您仍在将 UnicodeString 转换为 AnsiString,而 AnsiString 的编码在编译时未知。警告只会在您明确执行时消失,并且编译器会假定您知道自己在做什么。
如果转换工作取决于您系统上的编码设置:它是 UTF-8,那么 Actual
包含字符串 UTF-8 编码并且它工作,或者您系统上的特定语言环境支持您正在使用的字符。如果您 运行 在带有 e 的系统上使用此代码。 G。 CP1250,会失效。控制变量是 DefaultSystemCodePage
。在启动时,它由 FPC RTL 使用系统编码进行初始化。但是,有些框架(如 LCL)会覆盖它并将其设置为 e。 G。 UTF-8.
除了 {$mode delphi}
之外还使用 {$modeswitch unicodestrings}
,并且 string
等于 unicodestring
,因此编码将与语言环境无关。
此单元测试在 Delphi 模式下使用 Free Pascal 3.0 成功运行:
procedure TFreePascalTests.TestUTF8Decode;
var
Raw: RawByteString;
Actual: string;
begin
Raw := UTF8Encode('关于汉语');
Actual := string( UTF8Decode(Raw) ); // <--- cast from UnicodeString
CheckEquals('关于汉语', Actual);
// check Windows ANSI code page
CheckEquals(1252, GetACP);
// check Free Pascal value (determines how CP_ACP is interpreted)
CheckEquals(65001, DefaultSystemCodePage);
end;
UTF8Decode returns 一个 UnicodeString。如果没有将硬类型转换为字符串,编译器会警告不安全的转换:
Warning: Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"
(使用 Lazarus 1.6 / FPCUnit GUITestrunner 测试)
根据http://wiki.freepascal.org/Character_and_string_types#String,字符串类型默认为 AnsiString(如果 {$H+} 开关设置为使用 AnsiString 而不是 ShortString)。
看起来 Free Pascal 将 Unicode 字符串存储在 AnsiString 变量中。 (即使没有演员,测试成功)
问题:随着测试的成功,我是否可以假设使用强制转换(以抑制警告)是安全的而不会有数据丢失的风险?
转换通常不安全,因为您仍在将 UnicodeString 转换为 AnsiString,而 AnsiString 的编码在编译时未知。警告只会在您明确执行时消失,并且编译器会假定您知道自己在做什么。
如果转换工作取决于您系统上的编码设置:它是 UTF-8,那么 Actual
包含字符串 UTF-8 编码并且它工作,或者您系统上的特定语言环境支持您正在使用的字符。如果您 运行 在带有 e 的系统上使用此代码。 G。 CP1250,会失效。控制变量是 DefaultSystemCodePage
。在启动时,它由 FPC RTL 使用系统编码进行初始化。但是,有些框架(如 LCL)会覆盖它并将其设置为 e。 G。 UTF-8.
除了 {$mode delphi}
之外还使用 {$modeswitch unicodestrings}
,并且 string
等于 unicodestring
,因此编码将与语言环境无关。