的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
?
答案 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
部分。