在…中迭代使用for …的动态数组可以在数组中创建项目的副本吗?例如:
type TSomeRecord =record SomeField1 :string; SomeField2 :string; end; var list: array of TSomeRecord; item: TSomeRecord; begin // Fill array here for item in list do begin // Is item here a copy of the item in the array or a reference to it? end; end;
循环中的项目是数组中的项目的副本还是对其的引用?
如果是副本,可以遍历数组,而不创建副本?
谢谢,
AJ
解决方法
for / in循环的循环变量是循环正在循环的容器所保存的值的副本.
由于您无法替换动态数组的默认枚举器,因此您无法创建一个返回引用而不是副本的枚举器.如果要将数组包装在记录中,则可以为要返回引用的记录创建一个枚举器.
显然,如果您希望避免复制,您可以使用传统的索引for循环.
人们可能会问,因为上述语句似乎没有文档,为什么编译器不会选择使用引用而不是副本来实现这种for / in循环.只有设计师才能肯定地回答,但我可以提供一个理由.
考虑一个自定义的枚举器. documentation描述的机制如下:
To use the for-in loop construct on a class or interface,the
class or interface must implement a prescribed collection pattern. A
type that implements the collection pattern must have the following
attributes:
- The class or interface must contain a public instance method called
GetEnumerator()
. TheGetEnumerator()
method must return a class,
interface,or record type.- The class,interface,or record returned by
GetEnumerator()
must contain a public instance method calledMoveNext()
. TheMoveNext()
method must return aBoolean
. The for-in loop calls this method
first to ensure that the container is not empty.- The class,or record returned by
GetEnumerator()
must contain a public instance,read-only property calledCurrent
. The
type of theCurrent
property must be the type contained in the
collection.
自定义枚举器通过Current属性从集合返回每个值.这意味着该值被复制.
所以,这意味着自定义枚举器总是使用副本.想象一下,如果内置的数组枚举器可以使用引用.这将导致两种类型的枚举器之间的重大语义差异.设计人员选择了不同类型的枚举者的语义之间的一致性,肯定是合理的