Ruby符号是否等同于PHP常量?
看起来在记忆方面可能会有所不同,但在其他方面,它们似乎相当相似。我应该注意到的任何差异?ruby中的符号和PHP中的常量实际上并不等同Ruby符号是否等同于PHP常量?,php,ruby,symbols,Php,Ruby,Symbols,看起来在记忆方面可能会有所不同,但在其他方面,它们似乎相当相似。我应该注意到的任何差异?ruby中的符号和PHP中的常量实际上并不等同 大多数ruby实现都保留了一个称为符号表的东西,它位于解释器内部。符号表存储整个程序中使用的标识符,如所述表中的方法名、类名等。基于所述名称在符号表中的整数位置执行所述名称的查找 符号本身就是对象,符号名称和符号对象之间存在1对1的对应关系。因此,当您有例如def hello…并在程序中的某处调用hello方法时,这是指与您所指的:hello完全相同的对象。符号
大多数ruby实现都保留了一个称为符号表的东西,它位于解释器内部。符号表存储整个程序中使用的标识符,如所述表中的方法名、类名等。基于所述名称在符号表中的整数位置执行所述名称的查找 符号本身就是对象,符号名称和符号对象之间存在1对1的对应关系。因此,当您有例如
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指的是同一个对象。以这种方式存储符号可以减少对象分配——正如您所暗示的那样——并进一步提高在程序中查找常用名称的速度
此外,不能将值指定给符号。e、 例如,:hello=“blah”
不起作用。因为:根据内部符号表,hello有一个非常具体的值。这是ruby符号和PHP常量之间的另一个明显区别
在PHP中,常量是绑定到值的标识符,该值在程序执行期间是不可变的。该值可以是任何对象或值。如果有两个PHP常量引用相同的值,例如define(“A”,“value”)
和define(“B”,“value”)
,那么这实际上是指向两个唯一值的两个单独标识符
因此,虽然A
和B
指向相同的语义内容,但它们并不指向单个可识别对象。而且它们不会通过引用它们而简化为单个可识别对象。PHP中没有像ruby中的符号那样,保存公共符号到ID的映射的内部存储。所以我不会说ruby符号是PHP常量的等价物
[1] -他们之间没有任何关系。询问他们之间的差异就像询问丰田花冠和蓝色之间的差异 常量是(作为第一近似值)在初始化期间只能赋值一次的变量。常量是对值的不可变引用 符号是表示“名称”(在编程语言意义上)、“标识符”(在编程语言意义上)或“标签”概念的值。就像字符串一样,它也是一个表示“文本”概念的值。符号是不可变的、直接的,它们对自己进行评估
所以,符号是值,常数不是。(常量是对值的引用)。符号对其自身进行计算,常量对其引用的任何值进行计算。符号数据类型本质上向程序员公开了大多数语言实现(包括Peachpie、P8、Quercus和其他PHP实现)都有但通常没有公开的东西:符号表。符号不是Ruby所独有的,它们也存在于Smalltalk(Ruby从哪里获得它们)、Newspeak、Self、大多数Lisp(包括Clojure、Scheme、CommonLisp)、Elixir、Erlang、ECMAScript、Scala和许多其他语言中。PHP常量不能引用任何东西吗?@sawa-不,它们不能,例如,不能将对象放入常量中。直到最近,您还只能在其中放置原语(如果我记得PHP7现在允许常量数组的话)。也就是说我不知道Ruby是怎么做到的。但是说任何事都是广义的…:-我明白了。但是PHP似乎仍然允许更多的东西被称为常量。有用户定义的全局常量
define('constant',$value)
和类常量class foo{const constant=1;}
以及使用foo:constant代码>你也可以去$var='foo'然后是$var::Constant代码>但这可能会让你大吃一惊。无论是类常量
还是定义常量
都不能在运行时更改值。这就是为什么它们是常量。类常量很有用,因为它们不会弄乱全局空间,并且比全局常量更容易定位。“大多数ruby实现在解释器内部保留一个称为符号表的东西。”——几乎所有语言实现都有类似的东西,包括(我猜)大多数PHP实现(第8页,Quercus,Peachpie,等等)。区别在于Ruby,Smalltalk,Lisp,Erlang,Elixir等等。将它暴露给程序员。@JörgWMittag因为人类是编程的人…明白吗?