delphi – 带有接口字段的函数返回记录
发布时间:2020-12-15 03:55:34 所属栏目:大数据 来源:网络整理
导读:在询问 this question about interface fields in records之后我假设以下内容可行(注意断言): type TRec T = record Intf : IInterface; end; TTestClass = class public function ReturnRec : TRec Integer; end; // Implementation function TTestClass.R
在询问
this question about interface fields in records之后我假设以下内容可行(注意断言):
type TRec <T> = record Intf : IInterface; end; TTestClass = class public function ReturnRec : TRec <Integer>; end; // Implementation function TTestClass.ReturnRec : TRec <Integer>; begin Assert (Result.Intf = nil); // Interface field in record should be initialized! Result.Intf := TInterfacedObject.Create; end; 我用以下代码测试了这个: for I := 1 to 1000 do Rec := Test.ReturnRec; 并且断言失败了! 我的错在哪里?什么假设是错的? 解决方法
功能
function ReturnRec: TRec<Integer>; 在语义上等于过程 procedure ReturnRec(var Result: TRec<Integer>); [我很确定有人来自Embarcadero,可能是Barry Kelly或者Alan Bauer在某个地方说过这个,但我现在找不到参考资料.] 在第二种情况下,编译器假定记录将在传递给ReturnRec之前进行初始化(如果需要),并且不会在ReturnRec中为rec创建任何初始化代码.我假设第一个例子中的编译器内部使用了相同的代码路径,这就是为什么Result没有初始化的原因. 无论如何,解决方案很简单: function TTestClass.ReturnRec : TRec <Integer>; begin Result.Intf := TInterfacedObject.Create; end; 假设编译器知道它在做什么并分配接口,一切都会正常工作. 编辑 您遇到的问题来自’for’循环.你的代码 for I := 1 to 1000 do Rec := Test.ReturnRec; 编译成这样的东西: var result: TRec<Integer>; Initialize(result); for I := 1 to 1000 do begin Test.ReturnRec(result); rec := result; end; 这就是为什么你重复使用相同的记录,这就是为什么Result.Intf只是第一次未初始化. EDIT2 您可以通过将循环中的t.ReturnRec调用移到单独的方法来欺骗编译器. procedure GetRec(t: TTest; var rec: TRec); begin rec := t.ReturnRec; end; for i := 1 to 1000 do GetRec(t,rec); 现在隐藏的结果变量存在于GetRec过程中,并且每次调用GetRec时都会初始化. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |