我可以将set类型用作数组索引吗?

8

我不能将set类型用作数组的大小指示器,但对于小型集合来说,这样做是完全合理的。

假设我有以下代码:

  TFutureCoreSet = set of 0..15;
  TLookupTable = record
    FData: array[TFutureCoreSet] of TSomeRecord; //error ordinal type required
  ....

以下代码编译并运行正常。
  TFutureCoreSet = set of 0..15;
  TLookupTable = record
    FData: array[word] of TSomeRecord;

然而,这会破坏TFutureCoreSet中允许状态数量与查找表中元素之间的链接。
有没有一种简单的方法将两者联系起来,使得当一个发生改变时,另一个也会更新?


1
你会如何索引这样的数组?FData[[1, 2, 4]] := SomeRecord?考虑访问这种数组时的所有组合情况。 - Victoria
1
@Victoria,该集合有16位,因此数组将有64k个元素。您只需使用集合的序数值作为查找值即可。没有什么复杂的。在20位以内,使用查找表完全可行。但是,对于“set of byte”类型,这显然行不通 :-) - Johan
1个回答

12

稍微换个方式就可以了:

type
  TFutureCore = 0..15;
  TFutureCoreSet = set of TFutureCore;
  TFutureCoreIndex = 0..(2 shl High(TFutureCore)) - 1;
  TLookupTable = record
    FData: array[TFutureCoreIndex] of TSomeRecord;
  end;

使用 TFutureCoreIndex 的另一个好处是,您可以使用它将 TFutureCoreSet 强制转换为序数类型。 在将集合类型强制转换时,必须转换为相同大小的序数类型。

AllowedStates = LookupTable.FData[TFutureCoreIndex(FutureCores)]; //works
AllowedStates = LookupTable.FData[Integer(FutureCores)]; //invalid typecast
AllowedStates = LookupTable.FData[Word(FutureCores)]; //works, but not type safe.

我认为 1 shl ... - 1 是正确的。1 shl 16 = 65536,减一:65535。 - Rudy Velthuis
@RudyVelthuis,但是High(TFutureCore)是15,而2 shl 151 shl (15+1)相同。 - Uwe Raabe
是的,这也将解决您只能将集合强制转换为具有完全相同大小的整数类型的问题。顺便问一下,0..1 shl High(TFutureCore) 不是更简洁吗?或者我错过了什么。 - Johan
@Johan:1 shl 15 = 32768 - Uwe Raabe
shl比减号更强大! - Uwe Raabe
谢谢Uwe,那非常有帮助。 - Johan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接