【问题标题】:Delphi "Undeclared identifier" in constant array常量数组中的Delphi“未声明的标识符”
【发布时间】:2014-08-14 13:10:24
【问题描述】:

我有以下陈述:

type tx = Record
      a : string;
      b : integer;
     end;

const
     x : tx = (a: 'a'; b: 1);
     xs : array of tx = ((x));

编译器给了我:“Undeclared Identifier 'x'”

我不明白为什么,因为 'x' 是在 'xs' 数组声明和常量类型匹配之前声明的。我感谢任何启示;

【问题讨论】:

标签: constants delphi-xe4 delphi


【解决方案1】:

您原始答案中的代码不是导致您报告的错误消息的代码。我已尽力修复它,但发布实际代码而不是近似代码确实值得。

无论如何,假设这就是你所拥有的。

const
  x: tx = (a: 'a'; b: 1);
  xs: array of tx = ((x));

x 的声明很好。这定义了所谓的typed constant

xs的声明无效有两个原因:

  1. 您不能为动态数组类型声明类型化常量。
  2. 常量声明中的值必须是constant expressions。这排除了在任何常量声明中使用 x 作为值。

现在,从错误来看,您可能拥有的更像是这样的:

const
  x: tx = (a: 'a'; b: 1);
  xs : array [0..0] of tx = ((x));

这给出了您报告的错误。即:

E2003 未声明的标识符:'x'

这是因为我上面列表中的第 2 项。代码编译失败,因为x 不是常量表达式。

引用常量表达式的文档:

常量表达式是编译器可以在不执行它所在的程序的情况下计算的表达式。常量表达式包括数字;字符串;真正的常数;枚举类型的值;特殊常量 True、False 和 nil;以及使用运算符、类型转换和集合构造函数专门从这些元素构建的表达式。

请注意,类型化常量不会出现在列表中,这就是为什么您的 x 不是常量表达式。

考虑到这一切,你能做的最好的,声明一个常量,可能是:

const
  xs: array [0..0] of tx = ((a: 'a'; b: 1));

【讨论】:

  • x 的声明不正确。应该是b: 1,而不是b = 1
  • @RudyVelthuis 谢谢。事实证明,这个问题充满了错误。我天真地复制了它们。
  • @大卫:啧,啧,啧。 ;-)
【解决方案2】:

试试

const
  x1 : tx = (a: 'a'; b : 1);
  x2 : tx = (a: 'aa'; b : 11);
  xs : array[1..2] of tx = ( (a: 'a'; b : 1) , (a: 'aa'; b : 11) );

一些在线参考:

编辑:大卫的答案包含关键 - 常量定义不能使用本身不是常量的表达式。

【讨论】:

  • @Adrian 常量声明中的值必须是constant expressionsx1x2 不是常量表达式。
  • 大卫。你说的对。我错过了示例中的[0..0]constant expression 是编译器错误的答案。我的目标是在全球范围内声明 x : tx = (a: 'a'; b: 1); 声明并在许多 array [n..m] of tx 中使用它。你对我如何完成类似的事情有什么建议吗?
  • @user2383818 请阅读我的回答。我想我涵盖了那里的所有角度。
  • 大卫。您的回答说明了为什么我不能使用该语句序列。到现在为止还挺好。我现在要问的是,如何在应用程序的其他单元中使用全局声明的 const 声明 x : tx = (a: 'a'; b: 1);,而无需重新声明该声明。也许是StringList?我很感激任何建议。
  • @user2383818 我想我回答了你问的问题。如果您在我的答案中有 cmets,请将它们作为我的答案而不是 Adrian 的 cmets。如果您想发表评论,请使用 符号来通知收件人。如果您想提出新问题,请提出。
【解决方案3】:

我决定声明一个变量语句,它将全局常量保存为一个动态数组。在运行时,我使用特定单元所需的propper 常量语句填充该数组。

interface
...
type tx = Record
  a : string;
  b : integer;
end;
...
const x1 : tx = (a: 'a1'; b: 1);
      x2 : tx = (a: 'a2'; b: 2);
      x3 : tx = (a: 'a3'; b: 3);
...
var xs : array of tx; 
...
implementation
...
procedure SetXs;
begin
  SetLength (xs, 1);
  xs [0] := x1;
  SetLength (xs, 2);
  xs [1] := x3;
end;
...

我不知道这是最好还是最优雅的方式,但它现在适合我。我接受建议。谢谢。

【讨论】:

  • 这不能回答您提出的问题。这是您提供有关您当前如何考虑特定问题的更新。这里的网站都是关于问答的。如果您想发布答案,您必须解决所提出的问题。此外,这是初始化动态数组的一种非常糟糕的方法。将其声明为TArray<tx> 并使用xs := TArray<tx>.Create(x1, x3); 对其进行初始化
  • 大卫。它解决了我的实际目标,即(如果您已阅读我的 cmets)在本地声明的数组中使用全局声明的常量。如果我在发布问题时不够清楚,我深表歉意。我感谢每一位以某种方式帮助我找到上述解决方案的人。问候。
  • 大卫。使用Generics来初始化一个数组非常方便,但是我找不到Add的方法,所以我由此推断(如果我错了,请纠正我)在那种情况下,我必须使用传统的方式:SetLength 放大数组,然后将新值分配给数组中最近添加的项。是这样吗?
  • 您现在问的是不同的问题。我们不能先完成这个吗?
  • 大卫。好的,认为它完成了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 2012-06-27
相关资源
最近更新 更多