2

我在连接 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:= '';解决方案是在函数的开头简单地初始化结果。但问题是我为什么必须这样做?为什么这个字符串会被遗忘?

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

4

1 回答 1

5

Guido Gybels 在他的文章“在 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 帮助链接(处理函数结果部分)

于 2013-07-02T13:50:00.697 回答