似乎在内存方面可能存在差异,但除此之外,它们看起来非常相似。我应该注意哪些差异?
答案 0 :(得分:5)
Ruby中的符号和PHP中的常量并不是真正等效的。
大多数ruby实现都会保留一个称为解释器内部符号表的东西。符号表存储整个程序中使用的标识符,例如所述表中的方法名称,类名等。基于符号表中所述名称的整数位置来执行所述名称的查找。
符号本身就是对象,符号名称和符号对象之间存在一对一的对应关系。所以当你有例如def hello ...
并在程序中的某处调用hello
方法,这指的是与您引用:hello
时完全相同的对象。符号表基本上是一种在整个程序中引用常用名称时避免进行一堆字符串比较的方法。
为了说明,请考虑以下代码:
class A
def hello
puts "the method name is #{__method__}"
puts "the class of the method name is #{__method__.class}"
puts "the object ID of the name hello is #{__method__.__id__}"
end
end
A.new.hello
puts "the object id of :hello is #{:hello.__id__}"
输出:
$ the method name is hello
the class of the method name is Symbol
the object ID of the name hello is 898268
the object id of :hello is 898268
因此,方法名称'hello'和符号:hello引用同一个对象。以这种方式存储符号可以减少对象分配 - 正如您所暗示的那样 - 并且通过扩展可以更快地查找程序中常用的名称。
此外,您无法为符号指定值。例如,:hello = "blah"
将无效。因为:hello根据内部符号表具有非常具体的值。这是ruby符号和PHP常量之间的另一个明显区别。
在PHP中,常量是绑定到值的标识符,其值在程序执行期间是不可变的。值可以是任何对象或值。如果你有两个引用相同值的PHP常量,例如define("A", "value")
和define("B", "value")
,这实际上是指向两个唯一值的两个单独的标识符。
因此,虽然A
和B
指向相同的语义内容,但它们并不指向单个可识别对象。并且它们不会通过引用它们而简化为单个可识别对象。在PHP中没有内部存储,它保存了常见符号到ids的映射,就像ruby中的符号一样。所以我不会说ruby符号完全等同于PHP常量。
答案 1 :(得分:0)
他们彼此无关。询问他们之间的差异就像询问丰田卡罗拉和蓝色之间的差异一样。
常量是(作为第一个近似值)在初始化期间只能分配一次的变量。常量是对值的不可变引用。
符号是表示" name"的概念的值。 (在编程语言意义上),一个"标识符" (再次,在编程语言意义上),或者"标签"。就像一个字符串是一个代表" text"的概念的值。符号是不可变的,即时的,并且它们会自我评估。
因此,符号是值,常量不是。 (常量是到值的引用)。符号评估自己,常量评估他们引用的任何值。符号数据类型实际上向程序员公开了大多数语言实现(包括Peachpie,P8,Quercus和其他PHP实现)所具有的东西,但通常不会公开:符号表。符号并不是Ruby独有的,它们也存在于Smalltalk(Ruby从中获取),Newspeak,Self,大多数Lisps(包括Clojure,Scheme,CommonLisp),Elixir,Erlang,ECMAScript,Scala等等。