【问题标题】:Are Delphi strings immutable?Delphi字符串是不可变的吗?
【发布时间】:2009-04-16 12:49:59
【问题描述】:

据我所知,字符串在 Delphi 中是不可变的。我有点理解这意味着如果你这样做:

string1 := 'Hello';
string1 := string1 + " World";

第一个字符串被销毁,你得到一个对新字符串“Hello World”的引用。

但是,如果您在代码周围的不同位置使用相同的字符串会发生什么?

我分配了一个字符串哈希来标识多个变量,例如,“更改”由该更改的属性的哈希值标识。这样我就很容易检查“更改”是否相等。

现在,每个散列都是单独计算的(并非所有属性都被考虑在内,因此即使它们在某些值上不同,也可以分开实例)。

问题是,Delphi 如何处理这些字符串?如果我计算将散列分隔为相同的 10 字节长度字符串,我会得到什么?两个 10 字节的内存块还是对同一个内存块的两个引用?

澄清:更改由从数据库读取的一些属性组成,并由单个线程生成。 TChange 类有一个 GetHash 方法,该方法根据字符串中的某些值(但不是全部)计算哈希值。现在,其他线程收到更改并且必须将其与先前处理的更改进行比较,以便它们不会处理相同的(逻辑)更改。因此散列,并且由于它们具有单独的实例,因此计算了两个不同的字符串。我正在尝试确定从字符串更改为 128 位哈希之类的东西是否是一个真正的改进,否则只会浪费我的时间。

编辑:Delphi 的版本是 Delphi 7.0

【问题讨论】:

    标签: delphi string memory immutability


    【解决方案1】:

    Delphi 字符串在写入时复制。如果你修改一个字符串(不使用指针技巧或类似技术来欺骗编译器),对同一字符串的其他引用不会受到影响。

    Delphi 字符串不被保留。如果您从两个单独的代码部分创建相同的字符串,它们将不会共享相同的后备存储 - 相同的数据将被存储两次。

    【讨论】:

    • 我曾经在 DLL 中遇到字符串操作的问题,经过长时间的搜索,我发现 IsMultiThread 被设置为 false。它在 System.pas 中声明,在修改字符串引用计数和存储时使用。在我的初始化部分将其设置为 true 解决了我的问题。
    • Stijn - 引用计数机制使用总线锁定递增和递减指令来保证多线程的安全。这些虽然比正常的 inc 和 dec 慢。 IsMultiThread 是通过在 Delphi 中创建一个线程来设置的。当然,如果你在 Delphi 之外创建线程,或者使用原始的底层 API,它不会知道。
    【解决方案2】:

    Delphi 字符串不是不可变的(尝试:string1[2] := 'a'),但它们是引用计数和写入时复制的。

    您的哈希的后果尚不清楚,您必须详细说明它们的存储方式等。

    但是哈希应该只依赖于字符串的内容,而不是它的存储方式。这使整个问题变得无声。除非你能解释得更好。

    【讨论】:

    • 其实hash可以看成是一些信息的汇总,任何信息。这基本上就是我正在做的,将类中的值汇总为一个哈希,它恰好是一个字符串(哈希,而不是值!)
    【解决方案3】:

    正如其他人所说,Delphi 字符串不是通常是不可变的。这里有一些关于 Delphi 中字符串的参考资料。

    http://blog.marcocantu.com/blog/delphi_super_duper_strings.html

    http://conferences.codegear.com/he/article/32120

    http://www.codexterity.com/delphistrings.htm

    【讨论】:

      【解决方案4】:

      了解 Delphi 版本可能很重要。旧的 Delphi BCL 将字符串处理为写时复制,这基本上意味着当字符串中的某些内容发生更改时会创建一个新实例。所以是的,它们或多或少是不可变的。

      【讨论】:

      • 问题是......如果我从两个不同的代码部分生成相同的字符串怎么办?这不是写时复制...
      • BCL?我想你的意思是RTL。 (你说的不是 VCL;VCL 根本不控制字符串的工作方式。)
      • @Jorge:生成具有相同内容的字符串不会使其成为相同的引用。但这与不变性无关。 @Rob:嗯,BCL 代表基类库,RTL 就是其中之一...... ;)
      猜你喜欢
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 2011-08-06
      • 1970-01-01
      • 2010-09-08
      相关资源
      最近更新 更多