gpt4 book ai didi

delphi - 我如何使用 Move 过程来填充 TList 元素?

转载 作者:行者123 更新时间:2023-12-03 15:29:08 24 4
gpt4 key购买 nike

我需要将存储在字节数组中的数据移动到位于 TList 中的一组记录,但我收到此错误

E2197 Constant object cannot be passed as var parameter

此代码重现了该问题。

uses
System.Generics.Collections,
System.SysUtils;

type
TData = record
Age : Byte;
Id : Integer;
end;

//this code is only to show the issue, for simplicity i'm filling only the first
//element of the TList but the real code needs fill N elements from a very big array.
var
List : TList<TData>;
P : array [0..1023] of byte;
begin
try
List:=TList<TData>.Create;
try
List.Count:=1;
//here i want to move the content of the P variable to the element 0
Move(P[0],List[0], SizeOf(TData));

finally
List.Free;
end;

except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

如何将缓冲区的内容复制到 TList 元素

最佳答案

在XE2中,内部存储为TList<T>是不透明和隐藏的。您无法通过正常方式访问它。对列表元素的所有访问都会被复制 - 对底层存储的引用不可用。所以你不能使用 Move blit 到它。如果您想要一个可以位 block 传送的结构,您应该考虑动态数组, TArray<T>

您始终可以使用为 TList<TData> 实现类帮助器的技巧。这将公开私有(private)变量 FItems 。这很老套,但会按照你的要求做。

type
__TListTData = TList<TData>;
//defeat E2086 Type 'TList<T>' is not yet completely defined

type
TListTDataHelper = class helper for TList<TData>
procedure Blit(const Source; Count: Integer);
end;

procedure TListTDataHelper.Blit(const Source; Count: Integer);
begin
System.Move(Source, Pointer(FItems)^, Count*SizeOf(Self[0]));
end;

我猜你可能想在 TListTDataHelper.Blit 中进行一些参数检查,但我会把它留给你。

如果您使用的是XE3,您可以访问TList<T>的私有(private)存储。通过使用 List 属性。

Move(P, Pointer(List.List)^, N*SizeOf(List[0]));

如果您不需要 blit 并且可以使用 for 循环,那么可以这样做:

type
PData = ^TData;
var
i: Integer;
Ptr: PData;
....
List.Count := N;
Ptr := PData(@P);
for i := 0 to List.Count-1 do
begin
List[i] := Ptr^;
inc(Ptr);
end;

但我将你的问题解释为你希望避免此选项。

关于delphi - 我如何使用 Move 过程来填充 TList<T> 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14348498/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com