如何在TDictionary中使用record
TMyRec = record
a: Integer;
b: Integer;
end;
...
dictionary = TDictionary<String, TMyRec>.create();
...
dictionary[key].a := 30;<<<在这里,编译器给出了一个错误:“左侧不能被赋值”。在不创建单独的函数来编写myFunc(a, b: Integer): TMyRec的情况下,如何解决此问题
发布于 2018-11-30 15:32:15
dictionary[key]返回字典保存的记录的副本。编译器会阻止你修改它,因为它没有任何作用。
另外,旧版本的程序会接受您的代码,并且对记录的修改会丢失,这是非常令人困惑的。你做了一个赋值,但是没有任何可见的改变,因为你赋值的是一个无名的局部变量。
显然,您打算修改集合中保存的记录。为了做到这一点,你需要分配整个记录。将记录从集合读取到局部变量中。修改局部变量。将更新后的值写回集合。如下所示:
var
rec: TMyRec;
...
rec := dictionary[key];
rec.a := 30;
dictionary[key] := rec;其中一个令人沮丧的方面是,代码需要执行两次字典查找,即使我们知道第二次查找将找到与第一次相同的记录。即使是功能强大的Spring4d字典也不能通过一次查找就做到这一点。
发布于 2018-11-30 15:50:48
David Heffernans answer是你想要的,但我想提供一个额外的警告。记录可以有像类一样的属性,有getter和setter,如果你的记录有这样的属性,你的代码将被编译,但它仍然不会改变实际的记录值。
TMyRec = record
private
FA : integer;
procedure SetA(const Value: integer);
function GetA : integer;
public
{ Warning: When used on result from dictionary lookup, only the COPY will be
altered, not the actual record in the dictionary! }
property A : integer read GetA write SetA;
end;发布于 2020-04-26 06:58:47
一个非常简单的解决方法是使用记录的List属性。
你可以说:
dictionary.list[key].a := 30;
这将通过TList属性访问备份列表的动态数组。编译器已经支持对动态数组的直接访问。
如果您可以登录quality.embarcadero.com,您可以看到对此问题的完整讨论,提出的方式为:RSP-23136: We should be able to assign a value to one element in a list of records -发布于2018年12月18日,已解决于2019年11月21日。
这个问题以下面的评论结束:
“这按预期工作。提供了替代编码样式。”
https://stackoverflow.com/questions/53552368
复制相似问题