【问题标题】:Delphi - System.Copy good practicesDelphi - System.Copy 良好实践
【发布时间】:2012-03-22 14:29:09
【问题描述】:

据我所知,Delphi 中的字符串为 1,长度为 0。我负责一个用D5和D2006编写的庞大的应用程序,它正在使用从0索引开始复制的复制功能,现在几个同事也在这样编码。因为这是一个Delphi的“魔术”功能,我相信即使使用Copy从0索引复制字符串,在幕后它也会从位置1复制它。

对我来说,一个好的做法是从第一个位置复制一个字符串,而不是从 0 位置,即使结果是一样的。

现在,我的问题是,通过使用从 0 位置的复制功能而不是用于从 1 位置复制来传递到其他 Delphi 版本时,应用程序是否会受到影响?

【问题讨论】:

  • 只有老式的 ShortString 的长度在 0 位置。常用字符串(AnsiString等)的结构比较复杂
  • 自 Delphi 1 以来,字符串的长度一直不在索引 0 中,除非您明确声明 ShortString,如 var MyShortStr: ShortString; 或 `var MyShortString: String[255];'。您和您的同事应该偶尔购买一本书或阅读帮助文件。 :)

标签: delphi delphi-2006 delphi-5


【解决方案1】:

当将 0 作为 Index 参数传递给字符串的 Copy 时,Delphi RTL 会忽略您。当您为Index 传递0 或更少时,RTL 使用1 的值。因此,您所做的是良性的,因为在传递 1 或任何小于 1 的值之间没有明显的行为差异。但是,在 Delphi 中使用 0 作为字符串索引肯定会令人困惑,我建议不要这样做.

在伪代码中,Copy 的实现是这样开始的:

function Copy(s: string; Index, Count: Integer): string;
begin
  if Index<1 then
    Index := 1;
  dec(Index);//convert from 1-based to 0-based indexing
  ....continues

实际上实际的实现稍微复杂一些,但上面的伪代码给出了正确的语义。

您对存储在索引 0 处的长度的评论对于旧式短字符串是正确的。但对于长字符串则不是这样。事实上,正是这一事实导致了一种相当奇怪的情况,即字符串是从 1 开始的,而动态数组、列表等是从 0 开始的。

【讨论】:

  • 良性,只要它不崩溃。但是愚蠢,绝对是代码气味。如果我对这些人进行代码审查,我会指出这会如何导致各种开发人员的困惑,包括不合时宜的错误。
  • 我想知道将字符串语义更改为 0 索引会导致多少问题。如果您有 C++ Builder 代码,我会发现它特别令人困惑,因为它可以同时使用 (Delphi, 1-indexed) Strings 和 (C++ std, 0-indexed) wstrings ... 虽然说实话,访问一个字符的索引是非常罕见的事情。从记忆中,我认为 @Allen Bauer 曾经写过一篇博文,暗示 - 没有任何保证,我记得语气是“只是把它扔在那里” - 它可能有一天会改变。
  • 我发现索引为 1 的字符串是主要的 PITA。即使在我在这里发布的代码示例中,我也犯了用“0 到长度(stringThing)-1)”索引字符串的错误。所有其他的迭代器、stringLists、listViews、组件、控件等都是'0 to thingy.count-1',那为什么不是string chars呢?
  • @DavidM:在 C++Builder 中,AnsiStringUnicodeString 类实际上在其 [] 运算符中不接受索引 0,它们会引发索引越界异常。 WideString 类允许索引 0,但它不访问第一个字符,而是访问字符串长度字段的一部分。 WideString 似乎缺少一些范围检查。
  • @remy DavidM 没有说他们做到了。他说的是std::string和std::wstring。我不知道您对宽字符串的长度字段是什么意思。你是说短字符串吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-18
  • 2011-03-09
  • 2015-06-09
  • 2018-12-02
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多