请考虑以下代码段:
procedure TForm1.FormCreate(Sender: TObject);
{$REGION 'Sealed declarations'}
type WCh = WideChar; // (1)
type Str = ^WCh; // (2)
{ this routine accepts character pointer }
procedure Baz(Param: Str);
begin
end;
{$ENDREGION}
{ this one too, but character pointer type used directly }
procedure Bar(Param: PWideChar);
begin
end;
{ this constant should be compatible with strings and character pointers }
const FOO = 'FOO';
begin
Bar(FOO); // compiles!
Baz(FOO); // BAH! E2010 Incompatible types: 'Str' and 'string'
end;
如何解决此问题,同时保留声明中的结构化输入以及使用中的清晰度和可读性(我希望没有重大的类型转换)?
NB:通过“密封声明”,我的意思是。除非绝对必要,否则我宁愿不修改它。
string
和PChar
之间转换的内部处理因版本而异,因此环境可能很重要 - 我在Delphi XE中遇到此问题。
答案 0 :(得分:4)
正如Rob Kennedy在评论中正确注意到的那样,问题是从字符串 literal 转换而不是字符串 type 。
简化编码Delphi允许从字符串文字隐式转换为PChar
类型和PChar
别名。
为避免类型转换,您可以使用
type Str = PWideChar;
或使用distict类型
type Str = type PWideChar;
我没有注意到字符串文字有任何区别 - >在Unicode Delphi版本(2009及以上版本)中的PWideChar隐式转换。
答案 1 :(得分:1)
您的WCh = WideChar
定义为WideChar
创建了一个类型别名 - 他们有类型标识 - 但后续Str = ^WCh
定义不 >为PWideChar
创建一个类型别名。当$T+
生效时,它们兼容兼容并且可以兼容,但在这种情况下,这些都不够好。它们仍然是不同的类型。
FOO
常量是字符串文字。 documentation for assignment compatibility表示可以为字符串文字分配的类型:" PAnsiChar,PWideChar,PChar或任何字符串类型。" Str
不是字符串类型。它是指针类型,但它不是PWideChar
,尽管它们的定义有多么类似。
字符串文字的类型根据上下文进行调整。当编译器需要PWideChar
时,字符串文字是PWideChar
。当编译器需要AnsiString
时,它就是AnsiString
。 (如果编译器需要这两种类型,那么文字将以两种方式存储在程序中。)字符串文字不能分配给Str
类型,因此,根据错误消息,编译器显然选择string
作为该情况下字符串文字的类型。您可以将其类型转换为其他内置类型之一,但更好的解决方案是避免使用自定义字符指针类。