那么,为什么Ruby创建者必须symbols
在语言中使用的概念?
好吧,他们没有严格地“必须”,而是选择了。另外,请注意,严格来讲Symbol
s不是语言的一部分,它们是核心库的一部分。它们确实具有语言级的文字语法,但是如果您必须通过调用来构造它们,它们也将同样有效Symbol::new
。
我从试图理解它的非橄榄球程序员的角度出发。我学习了许多其他语言,但没有一个语言需要指定我是否处理Ruby所调用的语言symbols
。
您没有说那些“许多其他语言”是什么,但是这里只是一些Symbol
数据类型的摘录,这些数据具有像Ruby 这样的数据类型:
还有其他语言Symbol
以不同的形式提供s 的功能。例如,在Java中,Ruby的功能String
分为两种(实际上是三种)类型:String
和StringBuilder
/ StringBuffer
。另一方面,Ruby的Symbol
类型的特征被折叠成Java String
类型:Java String
可以被Interned,编译时求值常量表达式的结果的文字字符串和String
s被自动插入,动态生成的String
s可以通过调用被插入的String.intern
方法。一个被拘留String
Java中与Symbol
Ruby中的完全一样,但它不是作为单独的类型实现的,只是Java的不同状态。String
可以在其中。(注意:在Ruby的早期版本中,该方法String#to_sym
曾经被调用过,String#intern
并且该方法今天仍作为旧别名存在。)
主要问题可能是:symbols
Ruby中的概念是否作为其本身和其他语言的性能意图而存在,
Symbol
首先是具有特定语义的数据类型。这些语义还使实现某些性能操作(例如快速O(1)相等性测试)成为可能,但这并不是主要目的。
还是仅仅是因为语言的编写方式而需要存在的东西?
Symbol
根本不需要Ruby语言中的s,没有它们,Ruby也可以正常工作。它们纯粹是库功能。在语言中,与Symbol
s 紧密相关的只有一个地方:def
方法定义表达式的计算结果Symbol
表示所定义方法的名称。但是,这是一个相当新的变化,在此之前,未明确指定返回值。MRI仅评估为nil
,Rubinius评估为一个Rubinius::CompiledMethod
对象,依此类推。也可以将结果评估为UnboundMethod
…或仅评估为String
。
Ruby中的程序会比Python或Node对应的程序轻和/或快吗?如果是这样,那是因为symbols
吗?
我不确定您在这里问什么。性能主要取决于实现质量,而不是语言。另外,Node甚至不是一种语言,它是ECMAScript的事件I / O框架。在IronPython和MRI上运行等效的脚本,IronPython可能会更快。在CPython和JRuby + Truffle上运行等效的脚本,JRuby + Truffle可能会更快。这与无关Symbol
s而与实现的质量有关:JRuby + Truffle具有积极优化的编译器,再加上高性能JVM的整个优化机制,CPython是一个简单的解释器。
由于Ruby的目的之一是易于人类阅读和编写,因此它的创建者难道不能通过在解释器本身中实现这些改进来简化编码过程吗(就像其他语言一样)?
编号Symbol
不是编译器优化。它们是具有特定语义的单独数据类型。它们与YARV的flonums不同,后者是Float
s 的私有内部优化。这种情况是不一样的Integer
,Bignum
而且Fixnum
,这应该是一种无形的私人内部优化的细节,但不幸的是,没有。(这最终将在Ruby 2.4中修复,该版本删除了Fixnum
并Bignum
仅保留Integer
。)
作为Java的特殊状态,以Java的方式进行操作String
意味着您始终需要警惕String
s是否处于该特殊状态,以及在什么情况下它们会自动处于该特殊状态以及何时处于特殊状态。这比仅仅拥有一个单独的数据类型要高得多。
是否存在语言不可知的符号定义,以及将其用其他语言表达的理由?
Symbol
是表示名称或标签概念的数据类型。Symbol
s是值对象,是不可变的,通常是直接的(如果语言可以区分此类事物),无状态且没有身份。两个Symbol
相等也保证是相同的,换句话说,两个Symbol
S的相等实际上是相同的一个Symbol
。这意味着值相等和引用相等是同一件事,因此相等有效且为O(1)。
使用某种语言使用它们的原因实际上是相同的,而与该语言无关。有些语言比其他语言更多地依赖它们。
例如,在Lisp系列中,没有“变量”的概念。相反,你有Symbol
与关联的值。
在具有反射或内省能力的语言,Symbol
s的经常用来表示反映实体的名称在反射的API,如在Ruby中Object#methods
,Object#singleton_methods
,Object#public_methods
,Object#protected_methods
,和Object#public_methods
返回Array
的Symbol
S(尽管他们可能只是以及返回Array
的Method
多个)。Object#public_send
以一个Symbol
表示要发送的消息的名称作为参数(尽管它也接受String
,Symbol
在语义上更正确)。
在ECMAScript中,Symbol
s是将来使ECMAScript功能安全的基本构建块。它们在反思中也起着重要作用。