为什么形式[...]的文字具有看似依赖于背景的含义?

Dav*_*nan 5 delphi delphi-xe8

考虑以下程序:

{$APPTYPE CONSOLE}

type
  TMyEnum = (enum1, enum2, enum3);

var
  Arr: TArray<TMyEnum>;
  Enum: TMyEnum;

begin
  Arr := [enum3, enum1]; // <-- this is an array
  for Enum in Arr do
    Writeln(ord(Enum));
  Writeln('---');

  for Enum in [enum3, enum1] do // <-- this looks very much like the array above
    Writeln(ord(Enum));
  Writeln('---');

  Readln;
end.
Run Code Online (Sandbox Code Playgroud)

输出是:

2
0
---
0
2
---

为什么两个循环产生不同的输出?

Dav*_*nan 3

for Enum in Arr do
  Writeln(ord(Enum));
Run Code Online (Sandbox Code Playgroud)

这里,Arr是一个数组,因此数组中的项按顺序输出。文档

以升序遍历数组。

因此2是之前的输出0

for Enum in [enum3, enum1] do
  Writeln(ord(Enum));
Run Code Online (Sandbox Code Playgroud)

这里,[enum3, enum1]是一个集合,并且集合的枚举器恰好按顺序值递增的顺序进行枚举。所以输出是0第一位的。

我认为文档中没有任何地方说明集合是按该顺序枚举的,但从经验来看似乎确实如此。然而,由于集合是一种无序类型,因此无论如何都不应该依赖它们的枚举顺序。


因此,问题就变成了理解[...]代码中不同点如何成为集合或数组。这一切都源于新的 XE7 动态数组语法,它引入了(另一个)语法歧义。当我们写的时候

Arr := [enum3, enum1];
Run Code Online (Sandbox Code Playgroud)

然后[enum3, enum1]是一个数组。编译器知道这Arr是一个数组,并且该信息定义了文字的类型。

但是当我们写

for Enum in [enum3, enum1] do
Run Code Online (Sandbox Code Playgroud)

然后[enum3, enum1]是一个集合。这里的文字原则上可以是数组或集合。在这种情况下,我相信编译器总是更喜欢集合。

同样,我找不到任何文档表明情况如此,但从经验上来看确实如此。据推测,由于集合枚举器早于新的动态数组语法,因此当存在歧义时它们优先。

形式的字面意义[...]取决于其上下文。