人们可以将这种不相交的联合称为一种非常早期的多态性形式。您有一种可以有多种形式的类型。在某些语言中,使用这些形式中的哪一种(处于活动状态)是由类型的成员(称为标记)来区分的。这可以是布尔值、字节、枚举或其他一些序数。
在一些(旧的?)Pascal 版本中,标签实际上需要包含正确的值。Pascal“联合”(或者,在 Pascal 中称为变体记录)包含一个值,用于区分当前哪些分支是“活动的”。
一个例子:
type
MyUnion = record // Pascal's version of a struct -- or union
case Tag: Byte of // This doesn't have to be called Tag, it can have any name
0: (B0, B1, B2, B3: Byte); // only one of these branches is present
1: (W0, W1: Word); // they overlap each other in memory
2: (L: Longint);
end;
在此类 Pascal 版本中,如果 Tag 的值为 0,则您只能访问 B0、B1、B2 或 B3,而不能访问其他变体。如果 Tag 为 1,则只能访问 W0 和 W1 等...
在大多数 Pascal 版本中,没有这样的限制,标签值纯粹是提供信息。在其中许多中,您甚至不再需要显式标记值:
MyUnion = record
case Byte of // no tag, just a type, to keep the syntax similar
etc...
请注意,Pascal 变体记录不是纯并集,其中每个部分都是可选的:
type
MyVariantRec = record
First: Integer; // the non-variant part begins here
Second: Double;
case Byte of // only the following part is a "union", the variant part.
0: ( B0, B1, B2, B3: Byte; );
1: ( W0, W1: Word; );
2: ( L: Longint);
end;
在 C 中,您必须在结构中嵌套一个联合才能获得几乎相同的东西:
// The following is more or less the equivalent of the Pascal record above
struct MyVariantRec
{
int first;
double second;
union
{
struct { unsigned char b0, b1, b2, b3; };
struct { unsigned short w0, w1 };
struct { long l };
};
}