Delphi中一个"type"块和多个"type"块之间的区别是什么?

6

我已经编写Delphi程序五六年了,自认为还算比较擅长,但最近遇到一个行为问题却无法解释。我在编写一个简单的链表(叫做TIntegerList)时发现以下示例代码可以正确编译:

type
  PIntegerValue = ^TIntegerValue;

  TIntegerValue = record
    Value: Integer;
    Next: PIntegerValue;
    Prev: PIntegerValue;
  end;

然而,下面的代码不行(提示TIntegerValue未声明):
type
  PIntegerValue = ^TIntegerValue;

type  
  TIntegerValue = record
    Value: Integer;
    Next: PIntegerValue;
    Prev: PIntegerValue;
  end;

在Delphi中,“type”关键字的处理方式是什么?在一个“type”关键字下声明多个类型与每个类型声明一个“type”关键字相比,语法上有何意义?好吧,这很困惑,但我希望代码示例可以帮助解释我的意思。我正在使用Delphi 2007。

3个回答

9

当代码已经是现有类型声明部分的一部分时,逻辑上不需要使用type关键字。因此,

type
  TRec1 = record
  end;

  TRec2 = record
  end;

生成与其它类型无异的类型。

type
  TRec1 = record
  end;

type
  TRec2 = record
  end;

然而,正如您所发现的那样,编译器有一个限制,要求在引入前向声明的部分结束之前,必须完全解析所有前向声明。
这并没有什么特别的原因。编译器放宽这种限制是完全可行的。我们只能假设,编译器的实现细节(可能来自很久以前)已经泄漏到了语言规范中。

谢谢,这听起来就像我所期望的!没有真正的语法意义,只是编译器中某种程度上的任意限制 :) - kling
从Turbo Pascal程序员指南(TP6)关于指针类型的内容:“如果基类型是未声明的标识符,则必须在与指针类型相同的类型声明部分中声明它。” 在最新的Delphi版本中,Pointer Types有以下说明:“注意:您可以在声明所指向的类型之前声明指针类型。” - LU RD

2

这是纯标准的Pascal。由于Pascal编译器通常是单遍的,并且没有类型的前向声明,因此N. Wirth在原始Pascal中定义了此功能,以允许例如链表等“递归”类型。


1
这里要把“pass”关键字放在哪里? - David Heffernan
1
我也对你的历史提出质疑。我现在正在看《算法+数据结构=程序》,它就在我面前。链表是使用这个结构引入的:TMyRecord = record P: ^TMyRecord; end; - David Heffernan

0

我已经发表了一条评论,但需要同行评审。这样有些不太有效。因此,这里是另一个答案。这个答案可能会被合并或者你想怎么做都可以。

在《算法+数据结构=程序》中,Wirth在“程序4.1直接插入排序”中给出了一个例子。

type
  ref  = ^word;
  word = record
           key: integer;
           count: integer;
           next: ref
         end;

明天我会再次查看这个问题,因为我将与我的 A+DS=P 副本重逢。里面是否有陈述维尔斯原始语言中前向声明规则的语句?此外,您无需创建新的用户帐户。这样 SO 的效果不好。我会尝试为您合并它们。 - David Heffernan
你能否前往http://stackoverflow.com/help/user-merge并合并你的用户档案?谢谢。 - Kev
好的,我明白了。我正在查看4.3.1节。当然,在需要指针类型的前向声明之前,算法不需要非常复杂。例如,代码块4.28,第184页。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接