我想知道这种区别是否是由于历史原因造成的。我知道直接影响Java的语言有一个char类型,但没有字符串。相反,使用char*或char[]形成字符串。
但我不确定是否有实际目的这样做。我也很好奇在某些情况下一种方法是否比另一种方法更具优势。
为什么像Java这样的语言区分char基元和string类,而像Ruby和Python这样的语言却不区分呢?
肯定有某种设计上的考虑,无论是约定、效率、清晰度、易于实现等方面。语言设计师真的只是随机选择一个字符表示吗?
char
不同的byte
类型,甚至是short short int
,但考虑到70年代早期计算机的能力,那将是一种多余的浪费。 - Clifford编辑1:添加了一些来源链接;改进了关于Lisp的历史故事;解答了为什么Java有原始类型。
编辑2:解释了现代脚本语言的效率不再是如此重要的原因。
早期,内存非常昂贵 - 即使是简单的计算机也只有几千字节。您必须同意的典型服务条款将超过整个系统的RAM。这意味着数据结构必须比今天设计的数据结构小得多。
计算机起源于20世纪40年代的英国和美国,那时工程师所需的最小字符集是没有任何特殊字符的西欧字母表。0-9、A-Z和a-z总共62个字符。加上31个控制字符、空格和一些标点符号,就可以将它们全部放入7位中。完美地适用于电传打字机。
现在,这7位在不同的体系结构上可以以不同的方式布局。如果使用IBM,您必须知道EBCDIC,这与ASCII完全不同。
'60年代和'70年代的编程语言反映了这些问题,并将字符串压缩到最小的空间中:malloc
新内存并将字符串复制到新内存中,然后使用free
释放。随着国际化的增加,也带来了另一个问题 - 国际字符集。首先,ASCII被扩展到8位,作为ISO 8859-1适用于不同的欧洲语言(重音,希腊文,西里尔文),然后Unicode完全将计算机带到了世界的各个角落。这带来了字符编码的问题,例如UTF-8、UTF-16以及如何在这些不同的方法之间进行转换。
我还应该指出Lisp引入了垃圾回收。这解决了C语言中malloc/free的复杂性。Lisp的强大的数组和序列库自然地处理字符串。
第一个将这些趋势结合在一起的主要流行语言是Java。它结合了语言中的三个改进:
Character
和原始类型char
现在有些语言中每个值都是对象。然而,当Java在90年代末提出时,GC、JIT/Hotspot技术远没有现在快(至少部分原因是因为RAM限制,但算法也改进了)。Gosling很关心性能,所以保留了原始数据类型。
还有一点:在Java中,存在一个Character类是自然的 - 它是许多操作和实用方法的自然归属地,如isWhiteSpace()
和isLetter()
,后者由于日语、韩语和印度语而有些复杂。
现在,我对这个问题的看法可能与其他答案类似,但我还是要说一下:
是的,(像其他人提到的那样)像C这样的低级语言比像Perl、Ruby或Python这样的脚本语言更注重优化、性能和机器级细节。由于这种“全控制”思想的结果是,与脚本语言相比,你通常需要考虑更多的事情。
那么我想说什么呢?嗯,SO的一个成员曾经给我传递了“Python之禅”,其中有一些核心的Python哲学,比如“可读性很重要”、“简单比复杂好”,以及“做一件事应该有一种明显的方法,最好只有一种方法”。我强调了最后一句话。
接下来,这里有一个抽象编程语言的例子,它确实有一个char类型:SML。例如,我在交互模式下进行了两个语句的演示:
- val a = "a"
val a = "a" : string #interpreter type feedback
- val a = #"a"
val a = #"a" : char #interpreter type feedback
ctypes
库。char
只是一个“小”的整数。虽然它用于字符编码,但在至少支持各种语言和字母表的桌面系统或任何需要支持多种语言和字母表的系统面前,它的使用正在减少。然而,由于这些是能够直接访问硬件的“系统级”语言,因此还需要一种能够寻址特定架构上最小可寻址内存单元的数据类型;这就是为什么需要char
的原因。char
(实际上是16位)和最小可寻址单元类型byte
(8位)。这种清晰度可能是后来加入该领域的优势。
char
通常是一个字节(通常 翻白眼 - 是的,我在看你,Java)。这并不总是代表可读字符。另一方面,注意到类形式的string
通常是一组可读字符的集合(但不一定)。但无论如何,提供“字符串”功能需要额外开销。 - RageD