类型差异

Gu.*_*u. 2 delphi types compilation

德尔福.

为什么

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;

var 
  a: myint;
  b: myNewInt;

begin
  a := b;
end;
Run Code Online (Sandbox Code Playgroud)

它是正常编译的,虽然类型正式不同 - 一个在这里声明,另一个从其他模块承担.而如果

uses 
  windows;

type
   _FILETIMEA = record // Copy from windows.pas
     dwLowDateTime: DWORD;
     dwHighDateTime: DWORD;
   end;

var 
  x: _FILETIMEA;
  y: windows._FILETIME;

begin
  x := y;
end;
Run Code Online (Sandbox Code Playgroud)

但是会导致编译错误(在线x:=y; [DCC Error] ... E2010 Incompatible types: 'windows._FILETIME' and '_FILETIMEA')type _FILETIMEA = Windows._FILETIME吗?

And*_*den 9

Delphi不支持duck typing.你有2个不同的记录.它们看起来很像,但它们是编译器的两种不同类型.如果要分配两个变量,则必须键入它们,因为它们具有相同的大小.

x := _FILETIMEA(y);
Run Code Online (Sandbox Code Playgroud)

  • 这不是"非常悲伤".这是一件非常好的事情.它避免了代码中的大量错误和错误. (6认同)

Ken*_*ite 7

因为你没有做同样的事情.:) Delphi是强类型的(没有很多例外 - 几乎所有东西都有特定的类型).

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;
Run Code Online (Sandbox Code Playgroud)

这些类型没有任何不相容之处.它们都是相同的类型(整数),并支持相同的值范围.允许将一个分配给另一个没有冲突.

// Your unit name
unit GuTypes;

Type
 _FILETIMEA = record // Copy from windows.pas
   dwLowDateTime: DWORD;
   dwHighDateTime: DWORD;
 end;
Run Code Online (Sandbox Code Playgroud)

这是一种新类型,由您的代码定义(即使它与中的相同Windows.pas,但它不相同).它是GuTypes._FileTimeA,这是不一样的Windows._FileTimeA.

这实际上是一件好事,因为它允许不同的单位使用相同的类型名而不会发生冲突; 您可以使用单位名称作为"名称空间"作为前缀,以阐明您要使用的名称.例如,如果你在第三个单元中定义了你的GuTypes,并Windows在那里声明了一个MyAppCode,你可以安全地执行此操作:

var
  GFileTime: GuTypes._FILETIMEA;
  WFileTime: Windows._FILETIMEA;
Run Code Online (Sandbox Code Playgroud)

即使其中一种类型发生变化,您的代码也可以避免副作用,因为这两种类型不会意外地互换.

您可以强制转换以强制分配工作,但这通常是一个坏主意; 它违背了使用强类型语言的全部目的.类型转换告诉编译器"我比你聪明,我知道这是错的,但我希望你忽略它并且无论如何都要这样做."

更好的解决方案是y在示例(Windows._FILETYPEA)中声明变量,或声明兼容类型(type TMyFileTimeA = Windows._FILTETIMEA;).

XE2 wiki页面键入兼容性和身份.请特别注意该Assignment Compatibility部分.

  • 另请参阅[结构类型](http://docwiki.embarcadero.com/RADStudio/en/StructuredTypes.html),标题为"Records(traditional)"的部分; 在"记录中的变体部分"开始之前,查看最后一段代码片段及其后面的段落.它专门定义了一个本地化的`var s:record ...`并声明"......这种单独声明的记录不会与赋值兼容,即使它们的结构相同.",这似乎适用于发布的示例在关于记录声明的问题中. (3认同)