Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi字符串是不可变的吗?_Delphi_String_Memory_Immutability - Fatal编程技术网

Delphi字符串是不可变的吗?

Delphi字符串是不可变的吗?,delphi,string,memory,immutability,Delphi,String,Memory,Immutability,据我所知,字符串在Delphi中是不可变的。我理解这意味着如果你这样做: string1 := 'Hello'; string1 := string1 + " World"; 第一个字符串被销毁,您将获得对新字符串“Hello World”的引用 但是如果在代码的不同位置有相同的字符串,会发生什么呢 我分配了一个字符串散列来标识几个变量,因此,例如,“更改”由该更改的属性的散列值标识。这样,我就很容易检查“更改”是否相等 现在,每个散列都是单独计算的(并不是所有的属性都被考虑在内,这样,即使它

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

string1 := 'Hello';
string1 := string1 + " World";
第一个字符串被销毁,您将获得对新字符串“Hello World”的引用

但是如果在代码的不同位置有相同的字符串,会发生什么呢

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

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

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

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


编辑:Delphi版本是Delphi 7.0

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

Delphi字符串不是不可变的(try:string1[2]:=“a”),但它们是引用计数的,并且在写入时复制

哈希的结果不清楚,您必须详细说明它们是如何存储的等等


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

Delphi字符串是写时复制的。如果修改字符串(不使用指针技巧或类似技术愚弄编译器),对同一字符串的其他引用将不会受到影响


Delphi字符串不被占用。如果从两个独立的代码段创建相同的字符串,它们将不会共享相同的备份存储—相同的数据将存储两次。

正如其他人所说,Delphi字符串通常不是不变的。下面是一些关于Delphi中字符串的参考


问题是。。。如果我从两个不同的代码段生成相同的字符串呢?那不是抄写…BCL?我想你是说RTL。(你不是指VCL;VCL根本无法控制字符串的工作方式。)@Jorge:生成具有相同内容的字符串不会使其成为相同的引用。但这与不变性无关@罗布:好吧,BCL代表基类库,RTL就是其中之一……;)实际上,散列可以看作是某些信息的摘要,任何信息。这基本上就是我正在做的,将类中的值汇总成一个哈希,它恰好是一个字符串(哈希,而不是值!)我曾经在DLL中处理字符串时遇到问题,在长时间搜索后,我发现IsMultiThread被设置为false。它在System.pas中声明,并在修改字符串引用计数和存储时使用。在初始化部分将其设置为true解决了我的问题。Stijn-引用计数机制使用总线锁定递增和递减指令,以确保多线程的安全。但这比普通的inc和dec要慢。IsMultiThread是通过在Delphi中创建线程来设置的。当然,如果您在Delphi之外创建一个线程,或者使用原始的底层API,它将不知道。