将单元添加到接口或实现部分之间的区别 [英] Difference between adding a unit to the interface or the implementation section

查看:102
本文介绍了将单元添加到接口或实现部分之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个填充有常量的单位,例如...

If I have a unit that is filled with constants like...

unit AConsts;
interface
const
   Const1 : WideString = 'Const1';
   Const2 : WideString = 'Const2';
   Const3 : WideString = 'Const3';
   Const4 = 100;
   Const5 = 100;
implementation
end.

我想从另一个单元使用此单元,...之间有什么区别吗?

and I want to use this unit from another unit, is there any difference between...

unit AUnit;
interface
uses 
  AConsts;
Implementation
end.

unit AUnit;
interface
implementation
uses
  AConsts;
end.

问题不关乎范围,避免循环引用等。这与已编译的应用程序有关。

The question is not about scope, avoiding circular references etc. It is about differences in the compiled application.

如果 UnitA UnitB UnitC 都使用 AConsts ,会不会 App1 之间的已编译应用程序(假定 AConsts 单元中的常量与其他代码之间没有名称冲突),其中这些 UnitA UnitB UnitC 均具有 界面部分中的帐户 App2 其中的 UnitA UnitB UnitC 中都具有 AConsts 实施部分。

If UnitA, UnitB and UnitC all use AConsts, would there be a difference in the compiled application (assuming no name clashes between the constants in the AConsts unit and other code) between App1 where these UnitA, UnitB and UnitC all have AConsts in the interface section and App2 where UnitA, UnitB and UnitC all have AConsts in the implementation section.

推荐答案

区别在于您可以在何处引用 AConsts 在其界面部分中。在第一个 AUnit 中,可以使用 Const4 那个界面部分。您不能在第二个 AUnit 中执行此操作,因为 Const4 不在范围内。

The difference has to do with where you're allowed to refer to the things that AConsts has in its interface section. In the first AUnit, you could use Const4 to declare a fixed-size array in that interface section. You couldn't do that in the second AUnit because Const4 isn't in scope.

如果您不小心的话,它可能会对编译后的程序产生影响。假设我们有另一个 单元,其中声明了一个名为 Const4 的常量:

It can have an effect on the compiled program, if you're not careful. Suppose we have another unit that also declares a constant named Const4:

unit BConsts;
interface
const
  Const4 = 50;
implementation
end.

现在我们在 UnitA 中定义一个数组

Now we define an array in UnitA like this:

unit AUnit
interface
uses BConsts;
var
  data: array[0..Pred(Const4)] of Integer;
implementation
uses AConsts;
procedure Work;
var
  i: Integer;
begin
  for i := 0 to Const4 - 1 do begin
    data[i] := 8;
  end;
end;
end.

该代码将写入数组末尾,因为 Const4 与实现部分中使用的 Const4 不同。常量通常不会发生这种情况。通常只用两个标识符发生,即 Windows 中定义的 FindClose 函数和 SysUtils TBitmap ,在 Graphics Windows 。在这两种情况下,编译器会告诉您您做错了什么,尽管编译器不会准确地告诉您您使用了具有两种不同含义的标识符。您可以通过限定标识符来解决该问题:

That code will write beyond the end of the array because the Const4 that's in scope in the interface section is not the same Const4 that's used in the implementation section. This doesn't happen often with constants. It usually just happens with two identifiers, the FindClose function defined in Windows and SysUtils, and TBitmap, defined in Graphics and Windows. And in those two cases, the compiler will tell you that you've done something wrong, although it won't tell you precisely that you've used an identifier that has two different meanings. You can resolve the problem by qualifying the identifier:

for i := 0 to BConsts.Const4 - 1 do
  data[i] := 8;

如果上述所有注意事项都得到解决,则您的程序可以正确编译并运行,则没有任何区别使用单位的地方。在带有App1和App2的示例中,两个程序将相同。它们不是完全相同的-编译器将按不同的顺序处理事物,因此可能会将事物放在不同的位置-但这对程序的执行没有影响。

If all the above precautions are addressed, so your program compiles and runs correctly, then it makes no difference where units are used. In your example with App1 and App2, the two programs will be the same. They won't be identical — the compiler will have processed things in a different order and thus will likely put things in different places — but it will have no effect on the execution of your program.

这篇关于将单元添加到接口或实现部分之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆