类型差异

时间:2011-12-16 22:16:15

标签: delphi types compilation

的Delphi。

为什么

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

var 
  a: myint;
  b: myNewInt;

begin
  a := b;
end;

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

uses 
  windows;

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

var 
  x: _FILETIMEA;
  y: windows._FILETIME;

begin
  x := y;
end;

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

2 个答案:

答案 0 :(得分:9)

Delphi不支持鸭子打字。你有2个不同的记录。它们看起来很像,但它们是编译器的两种不同类型。如果你想要分配两个变量,你必须输入它们,因为它们具有相同的大小。

x := _FILETIMEA(y);

答案 1 :(得分:7)

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

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

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

// Your unit name
unit GuTypes;

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

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

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

var
  GFileTime: GuTypes._FILETIMEA;
  WFileTime: Windows._FILETIMEA;

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

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

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

请参阅XE2 Wiki Pages上的Type Compatibility and Identity。请特别注意Assignment Compatibility部分。