【问题标题】:Left over string in function result函数结果中的剩余字符串
【发布时间】:2013-06-29 21:34:09
【问题描述】:

我在连接 JSON 文本的对象中有一个函数。函数结果是一个字符串 - 生成的 JSON 文本。该函数只是将文本附加到结果的末尾...

function TDestination.GetAsJSON: String;
  procedure A(const Text: String);
  begin
    Result:= Result + Text + sLineBreak;
  end;
begin
  A('        {');
  A('            "name":"'+EncodeStr(FName)+'",');
  A('            "directory":"'+EncodeStr(FDirectory)+'",');
  A('            "description":"'+EncodeStr(FDescription)+'"');
  A('        }');
end;

在循环中从另一个父对象中重复调用此函数...

function TDestinations.GetAsJSON: String;
  procedure A(const Text: String);
  begin
    Result:= Result + Text + sLineBreak;
  end;
var
  X: Integer;
begin
  A('    [');
  for X := 0 to Count - 1 do begin
    if X > 0 then A('        ,');
    Result:= Result + Items[X].AsJSON;
  end;
  A('    ]');
end;

在第二个函数中,Items[X].AsJSON 正在调用第一个函数。

问题是对TDestination.GetAsJSON 的第二次(以及所有进一步的)调用仍然在函数结果中保留上次调用它的字符串。

解决方案是简单地在函数开头使用Result:= ''; 初始化结果。但问题是我为什么必须这样做?为什么这个字符串会被遗忘?

令人费解的是,对该函数的每次不同调用都来自该对象的一个​​完全独立的实例。如果它是完全相同的对象实例,我会理解,但不是。

【问题讨论】:

  • 您必须将 Result 作为局部变量处理
  • 以这种方式对待它是导致这个问题出现问题的原因,@Sir。 Result 名义上是一个局部变量,但它的作用与其他局部字符串变量不同。其他字符串变量总是初始化为空,但Result不是。
  • 结果不是局部变量。这是一个 var 参数。 Delphi 设计中做出的最糟糕的决定之一。你任由来电者摆布。并且有一个循环优化让你很痛苦。这是一个骗局。我明天查一下。另一个 Q IIRC 有一些好东西。
  • Delphi: function Result not emptied during for loop 的可能重复但是应该有一个更好的解释在那里接受的答案。我会努力完善它。

标签: delphi function concatenation


【解决方案1】:

Guido Gybels 在他的文章“Using Assembler in Delphi”中表示具有长字符串类型结果的函数将其作为隐式 var 参数返回。因此编译器将您的函数视为:

(hidden)var 
          temp_s: String;
procedure GetAsJSON(var temps: String);
...
GetAsJSON(temp_s);
UsedResult1 := temp_s;
...
GetAsJSON(temp_s);
UsedResult2 := temp_s;

所以隐藏字符串在特定条件下可以保持其值。

不管怎样,你不依赖0初始化整数结果,对吧?

编辑:此行为已记录在案:Delphi help link(处理函数结果部分)

【讨论】:

  • +1 用于引用 Delphi 链接的官方文档。请注意,在 x64 下,情况并非如此:string 结果作为第二个参数传递,而不是作为最后一个参数传递。但是对于这个问题,它和 x86 中的一样:结果是 neverfunction 的开头设置为''。仅当目标变量已经是 '' 时,它才会是 '',循环中不会出现这种情况。
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2016-05-10
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
相关资源
最近更新 更多