为什么 String 被设计为引用类型而不是值类型?
从建模的角度来看,我会将它建模为一个值类型,因为它代表了没有身份的东西。它没有区别属性。(例如,我无法区分一个字符串“a”和另一个字符串“a”)
我知道如果将长字符串存储在堆栈中,我会遇到严重的性能问题。可能这是不可能的,因为字符串会变得很长,因为堆栈的大小是有限的。
如果不是为了性能,为什么要将 System.String 设计为引用类型?(假设任何可能的字符串最长为 16 个字节)
为什么 String 被设计为引用类型而不是值类型?
从建模的角度来看,我会将它建模为一个值类型,因为它代表了没有身份的东西。它没有区别属性。(例如,我无法区分一个字符串“a”和另一个字符串“a”)
我知道如果将长字符串存储在堆栈中,我会遇到严重的性能问题。可能这是不可能的,因为字符串会变得很长,因为堆栈的大小是有限的。
如果不是为了性能,为什么要将 System.String 设计为引用类型?(假设任何可能的字符串最长为 16 个字节)
正如您指出的那样,由于堆栈空间有限和值类型的使用时复制语义,可能会变得非常巨大的值类型可能会令人望而却步。
此外,在 .NET 中实现字符串的方式为等式添加了一些元素。字符串不仅是引用类型,它们也是不可变的(无论如何都在 System 命名空间之外),并且运行时使用实习来为字符串做巧妙的技巧。
所有这一切都带来了几个好处:重复的文字字符串只存储一次,并且此类字符串的比较变得非常有效,因为您可以比较引用而不是 Unicode 字符流。这些选项对于值类型是不可能的。
结构需要固定大小。string[]
例如,想想一个。作为值类型的唯一方法string
是只存储指针。这本质上是我们通过使用引用类型实现的。
当然,每次分配字符串时不要复制字符串也是非常有益的。
我的理解是字符串是不可变的类而不是结构,只是为了提高性能。
往往会创建字符串,然后将其传递给许多对象以呈现给用户或交给其他系统。字符串创建后往往不会发生变化,因此将整个字符数组复制为每个对象中的唯一值几乎没有实用价值,并且会创建大量临时对象。
很简单——因为我不想每次将字符串传递给方法时都复制字符串。它需要更多的内存,也需要更多的时间。
有一点是,许多语言中的 String 类型都被编码为 Unicode,因此将它们视为原始类型(如int
)是不合逻辑的,因为它的二进制编码与其人类阅读形式之间没有直接对应关系。
Unicode 层自动限定要从二进制中抽象出来的字符串类型,而数字在base 2(二进制)和 base 10(十进制)形式之间可以相对容易地互换。
原始变量可以驻留在堆栈上的原因是有足够的空间可容纳大量数字。对于数据 String
量更大的类型,情况并非如此。
对字符串执行的操作类型并不是真正的算术,而是更多基于布尔逻辑(除非在将字符串视为向量或数组时计算字符串),因此通过系统优化数据结构以用于其主要用途是有意义的.String 命名空间。
就等式而言,您仍然可以将其视为带有==
运算符的值类型。
因此,如果有的话,将其作为参考是公正和有利的吗?