gpt4 book ai didi

string - 为什么 TPageProducer 不删除字符串中的引号?

转载 作者:行者123 更新时间:2023-12-03 14:47:36 27 4
gpt4 key购买 nike

我正在尝试调试仅在我的大型应用程序(在 XE3 中工作正常)在使用 XE4 编译后运行时才出现的行为。该问题似乎导致一些带引号的字符串(例如“MyString”)即使在 Web.HTTPProd 中被 TPageProducer“取消引用”后仍保留其引号。例如,考虑下面的代码,它是来自 Delphi 源单元 Web.HTTPApp 的小摘录:

procedure ExtractHeaderFields(Separators, _WhiteSpace: TSysCharSet; Content: PChar;
Strings: TStrings; Decode: Boolean; StripQuotes: Boolean = False);
{$ENDIF NEXTGEN}
var
Head, Tail: PChar;
EOS, InQuote, LeadQuote: Boolean;
QuoteChar: Char;
ExtractedField: string;
{$IFNDEF NEXTGEN}
WhiteSpaceWithCRLF: TSysCharSet;
SeparatorsWithCRLF: TSysCharSet;
{$ENDIF !NEXTGEN}

function DoStripQuotes(const S: string): string;
var
I: Integer;
InStripQuote: Boolean;
StripQuoteChar: Char;
begin
Result := S;
InStripQuote := False;
StripQuoteChar := #0;
if StripQuotes then
begin
for I := Result.Length - 1 downto 0 do
if Result.Chars[I].IsInArray(['''', '"']) then
if InStripQuote and (StripQuoteChar = Result.Chars[I]) then
begin
Result.Remove(I, 1);
InStripQuote := False;
end
else if not InStripQuote then
begin
StripQuoteChar := Result.Chars[I];
InStripQuote := True;
Result.Remove(I, 1);
end
end;
end;

当我使用 TPageProducer 时,我看到这个被调用,并且我可以看到我好的源字符串进入上面的 ExtractHeaderFields 例程,然后进入“DoStripQuotes”函数。进入 DoStripQuotes 并观察“Result”,结果表明即使调用 Result.Remove(以删除引号),它也不会更改。当我将此“DoStripQuotes”例程带到一个简单的测试应用程序中时,它不会编译,告诉我不允许“Result.anything”。我假设 Result 尽管被定义为“字符串”,但它必须是 Web.HTTPProd 上下文中的另一种类型的字符串。

所以我开始思考这可能与我听说过的“不可变字符串”有关。我读过这个SO question关于这一点,虽然我明白了要点,但我可以提供更实用的建议。

具体来说,我想要以下问题的答案:

  1. 如果允许使用 Result.Length 表示法,什么类型的“字符串”是“结果”?
  2. 有没有办法告诉编译器对单元使用“XE3”兼容性? (这可能会让我看到问题的根源)。我尝试过 {$ZEROBASEDSTRINGS ON}/OFF 但这似乎会导致更多困惑,我不知道我在做什么!

感谢您的帮助。

稍后编辑:正如下面接受的答案中所指出的,这是 VCL 单元 Web.HTTPApp.pas 中的一个错误,它应该在第 2645 行周围的两个地方读取“Result := Result.Remove(I,1)”,而不是“结果.删除(I,1)”

最佳答案

What type of 'string' is 'Result' if the notation Result.Length is allowed?

这只是您自 Delphi 2009 以来一直使用的旧 string,别名为 UnicodeString。不同之处在于此代码使用新的记录助手(具体为 SysUtils.TStringHelper)。这就是让您可以在字符串变量上使用 . 表示法的原因。

Is there a way in which I can tell the compiler to use 'XE3' compatibility for a unit?

没有。所讨论的代码是一个库单元,它被设计为以特定模式进行编译。而且,除非您自己编译 RTL/VCL,否则您无法轻松地重新编译它。即使有这样的模式,也无济于事,因为代码根本就是错误的(见下文)。再多的模式切换也无法修复这段特定的代码。

I get to thinking maybe this is something to do with the Immutable strings that I've heard about.

事实并非如此。 Delphi 编译器还没有不可变字符串。不可变字符串的概念只是作为 future 变化而提出的。如果进行了更改,预计将首先在移动编译器中进行。

<小时/>

问题实际上只是您发布的代码中的一个相当简单的错误,显然根本没有进行任何测试。 Remove 的使用是错误的。该方法不会就地修改字符串。相反,它返回一个删除了该字符的新字符串。代码应为:

Result := Result.Remove(I, 1);

编码 ExtractHeaderFields 的开发人员犯此错误的原因是设计字符串帮助器代码的人错误地命名了 Remove 方法。由于 Remove 是一个动词,您希望它就地操作。不修改主题并返回新实例的方法(如该方法所做的那样)应该指定一个名词名称。所以这个方法应该命名为Remnants。在我看来,RTL 设计者似乎复制了 .net 命名,但也存在同样的缺陷。

您应该提交一份质量控制报告(如果尚不存在)。我知道XE4更新1刚刚发布。它似乎包含修复程序。

据我所知,您的其他选择是:

  1. 坚持使用 XE3,直到 XE4 得到充分调试。
  2. 在您的项目中包含 Web.HTTPApp 单元的副本并自行修复错误。

关于string - 为什么 TPageProducer 不删除字符串中的引号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17061508/

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