Ruby 符号是否等同于 PHP 常量?

Are Ruby symbols the equivalent of PHP constants?

似乎在内存方面可能有所不同,但在其他方面,它们看起来非常相似。我应该注意哪些差异?

ruby 中的符号和 PHP 中的常量实际上并不等同。

大多数 ruby 实现保留解释器内部称为符号 table 的东西。符号 table 存储整个程序中使用的标识符,如方法名称、class 名称等 table 中的名称。根据所述名称在符号 table 中的整数位置执行所述名称的查找。

符号本身就是对象,符号名称与符号对象是一一对应的。所以当你有例如def hello ... 并在程序中的某处调用 hello 方法,这指的是与您引用 :hello 完全相同的对象。符号 table 基本上是一种避免在整个程序中引用常用名称时进行一堆字符串比较的方法。

为了说明,请考虑以下代码:

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 根据内部符号 table 具有非常具体的值。所以这是 ruby 符号和 PHP 常量之间的另一个明显区别。

在PHP中,常量是绑定到某个值的标识符,其中该值在程序执行期间为 immutable。该值可以是任何对象或值。如果您有两个引用相同值的 PHP 常量,例如define("A", "value")define("B", "value"),那么这其实是两个独立的标识符,指向两个唯一的值。

因此,虽然 AB 指向相同的语义内容,但它们并不指向单个可识别的对象。并且它们不会通过引用它们来简化为单个可识别的对象。 PHP 中没有像 ruby 中的符号那样保存常用符号到 id 的映射的内部存储。所以我不会说 ruby 符号完全等同于 PHP 常量。

[1] - https://ruby-doc.org/core-2.2.0/Symbol.html

他们之间没有任何关系。询问它们的区别就像询问丰田卡罗拉和蓝色之间的区别。

A constant 是(作为第一个近似值)在初始化期间只能分配一次的变量。常量是对值.

的 immutable 引用

符号是一个值,表示 "name"(在编程语言意义上)、"identifier"(同样,在编程语言意义上)或 "label".就像一个字符串是一个代表"text"的想法的值。符号是 immutable,直接的,并且它们对自己求值。

所以,符号是值,常数不是。 (常量是对 值的引用)。符号对自身求值,常量对它们引用的任何值求值。符号数据类型本质上向程序员公开了大多数语言实现(包括 Peachpie、P8、Quercus 和其他 PHP 实现)具有但通常不公开的东西:符号 table。符号不是 Ruby 独有的,它们也存在于 Smalltalk(Ruby 从那里得到)、Newspeak、Self、大多数 Lisp(包括 Clojure、Scheme、CommonLisp)、Elixir、Erlang、ECMAScript、 Scala 和许多其他语言。