Delphi:const对象的const列表

时间:2017-01-31 15:44:16

标签: arrays list delphi const

我将KnownFolderPath ID声明为consts:

const
  FOLDERID_LocalAppData  : TGUID = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData: TGUID = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents     : TGUID = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
  {...}

我想在编译时定义文件夹ID的有序列表。我知道我可以做到以下几点:

const
  settings_roots: array[0..2] of TGuid = (
    '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}',
    '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}',
    '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}'
  );

但这不方便维护代码,所以我想使用之前定义的名称。但这给了我Delphi XE3编译器错误(期望const表达式):

const
  settings_roots: array[0..2] of TGuid = (
    FOLDERID_LocalAppData, FOLDERID_RoamingAppData, FOLDERID_Documents
  );

我可以将FOLDERID定义为const字符串,如

const
  FOLDERID_LocalAppData   = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents      = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
  {...}

但是我必须在代码中每个地方都转换StringToGUID()的ID。在Delphi中运行之前,是不是可以在某种程度上定义const对象的有序static / const列表?

2 个答案:

答案 0 :(得分:3)

为了在数组声明中按名称使用ID常量,您需要从ID常量声明中删除TGuid类型,使它们成为"真常量"而不是"键入的常量":

const
  FOLDERID_LocalAppData = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
  {...}

这包含在Embarcadero的文档中:

Declared Constants

  

真实常数

     

true常量是声明的标识符,其值不能更改。例如:

const MaxValue = 237;
     

声明一个名为MaxValue的常量,返回整数237.声明一个真常量的语法是:

const identifier = constantExpression
     

其中identifier是任何有效的标识符,constantExpression是编译器可以在不执行程序的情况下评估的表达式。

     

...

     

常量表达式

     

常量表达式是编译器可以在不执行其发生的程序的情况下进行求值的表达式。常量表达式包括数字;字符串; 真常量;枚举类型的值;特殊常量TrueFalsenil;和表达式由这些元素专门构建,包含运算符,类型转换和集合构造函数。

     

...

     

键入的常量

     

与常量不同,类型常量可以包含数组,记录,过程和指针类型的值。 常量表达式中不能出现类型常量

     

...

     

数组常量

     

要声明一个数组常量,请在声明末尾的括号中用逗号分隔数组元素的值。 这些值必须用常量表达式表示。

声明类型常量通常很有用,您可以在不重复值的情况下执行此操作,例如:

const
  FOLDERID_LocalAppData = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
  {...}

  FOLDERID_LocalAppData_GUID: TGUID = FOLDERID_LocalAppData;
  FOLDERID_RoamingAppData_GUID: TGUID = FOLDERID_RoamingAppData;
  FOLDERID_Documents_GUID: TGUID = FOLDERID_Documents;
  {...}

  settings_roots: array[0..2] of TGuid = (
    FOLDERID_LocalAppData, FOLDERID_RoamingAppData, FOLDERID_Documents
  );

或者,TGuid类型的常量可以匹配Win32 API命名方案:

const
  FOLDERID_LocalAppData_STR = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData_STR = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents_STR = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';
  {...}

  FOLDERID_LocalAppData: TGUID = FOLDERID_LocalAppData_STR;
  FOLDERID_RoamingAppData: TGUID = FOLDERID_RoamingAppData_STR;
  FOLDERID_Documents: TGUID = FOLDERID_Documents_STR;
  {...}

  settings_roots: array[0..2] of TGuid = (
    FOLDERID_LocalAppData_STR, FOLDERID_RoamingAppData_STR, FOLDERID_Documents_STR
  );

答案 1 :(得分:-1)

可悲的是,答案似乎是否定的。你做了以下的

const
  FOLDERID_LocalAppData   : TGUID = '{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}';
  FOLDERID_RoamingAppData : TGUID = '{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}';
  FOLDERID_Documents      : TGUID = '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}';

  const
  settings_roots: array[0..2] of ^TGuid = (
    @FOLDERID_LocalAppData, @FOLDERID_RoamingAppData, @FOLDERID_Documents
  );

但是你需要像这样分配

  iGUID := settings_roots[ i ]^;

不确定这是否可以接受。如果愿意,你可以在它周围放一个类包装器。