了解联合类型

Understanding union types

在 Pascal 中可以声明联合类型:

AnimalType = (Dog, Cat);

Animal = record
  name: string;
  case myType: AnimalType of
    Dog: (weight: Integer);
    Cat: (age: Integer);
end;

但是,很容易违反case的约定:

var
  a: Animal;
begin
  a.name := 'Kittie';
  a.myType := Cat;
  a.weight := 10; // There is no weight for cats!

  writeln(a.age); // Prints 10
end.

此示例中存在语义错误,但编译器成功对其进行了类型检查。另外,运行时也没有报错。

那么,case 块是否仅用于文档目的?

联合使得为变量提供多种类型成为可能。在您的示例中,weightage 存储在内存中的相同位置。

如果你想要'typesafe union',你应该使用继承。

您问题的简短回答是 "no case blocks in variant records are not there only for documentation purposes"。我这样说是因为虽然您使用的 Pascal 实现没有检测到该程序访问非活动变体这一事实,但其他实现确实检测到了这个错误。

您问题的详细回答如下。

许多刚刚学习 Pascal 的人并没有意识到 Pascal 语言有两种主要的风格。有 ISO 7185 Standard Pascal(或简称 Standard Pascal)和 Turbo/Borland Pascal(最流行的变体)。那么让我给你两个问题的答案 "So, does the case block exist only for the documentation purposes"?

标准 Pascal 答案

标准 Pascal 将错误定义为 "A violation by a program of the requirements of this International Standard that a processor is permitted to leave undetected"。所以是的,您提供的程序确实包含错误,是的,您使用的处理器(即 Pascal 实现)没有检测到它,但其他实现会检测到它,因此变体记录中的 case 块实际上没有功能用途。

Turbo/Borland答案

就 Turbo/Borland Pascal 风格而言,我不知道它们中的 none 是否会检测到此错误,但即使它们中的 none 检测到了,也可能是最好将此视为他们未检测到的错误,而不是仅用于文档目的的错误。说某事仅用于文档目的,对我来说听起来像是说它从未打算发挥作用。