Ruby中的符号和变量有什​​么区别? [复制]

Posted

技术标签:

【中文标题】Ruby中的符号和变量有什​​么区别? [复制]【英文标题】:What is the difference between a symbol and a variable in Ruby? [duplicate] 【发布时间】:2014-09-16 13:30:48 【问题描述】:

我试图了解 ruby​​ 中的符号和变量之间的区别。他们似乎在给出一个引用对象的名称时做了完全相同的事情。

我已经阅读了下面的符号以获得更快的程序,但我不确定它们为什么或如何与变量有任何不同。

【问题讨论】:

另见“What is the colon operator in Ruby?”。 【参考方案1】:

它们完全不同。变量给对象一个标签。符号更像字符串,只是它们是不可变的并且驻留在内存中,因此对同一符号的多次引用不会占用额外的内存。 (与字符串相比,对同一字符串的多次引用将导致该字符串的多个副本。)

【讨论】:

通过变量引用字符串会不会做同样的事情并将一个实例保留在内存中?同在JS中使用变量防止重复,只获取一次相同的数据。 @Cameron:嗯,在类似a = "string", b = a 的情况下,是的。在a = "string"; b = "string" 的情况下,将创建两个内容为“字符串”的对象。 (我不确定 JS 是如何处理这个问题的。)【参考方案2】:

符号是一个“内部化”的字符串,它更像是一个常量而不是任何东西。典型例子:

account_details = 
  :name => 'Bob',
  :age => 20

这里的符号 :name:age 是哈希的键。不要将它们与变量混淆。 account_details 是一个变量。

Ruby 中的变量是某种对象的句柄,而该对象可能是一个符号。

通常在使用字符串时使用符号会导致大量重复。请记住,字符串通常是不同的对象,其中不同的符号始终指代同一个对象,如果经常使用它们会更有效。

比较:

"string".object_id == "string".object_id
# => false

:string.object_id == :string.object_id
# => true

即使这两个字符串相同,它们也是独立的字符串对象。当用作散列的键、方法的参数和其他常见情况时,这些对象会因大量重复而迅速使您的内存变得混乱,除非您不遗余力地使用相同的字符串实例。符号会自动为您执行此操作。

【讨论】:

感谢您的回复,我认为我的困惑来自使用带有属性的符号。在为实例变量编写属性读取器时,在属性中使用了一个符号,但返回了一个变量。在这种情况下,符号与实例变量有何关系? attr_accessor :example 表示“定义一个名为'example'的读/写属性”并定义了方法example和example=`以及实例变量@example。参数作为符号传入,因此接收方法可以知道它是什么。请记住,变量名是本地的,永远不会传入变量名。attr_reader example 的意思是“使用 example 希望调用的任何变量创建一个读取器”。 attr_reader 函数无法知道变量的名称。这里的关系是符号用于传达所需的名称。【参考方案3】:

变量持有对对象的引用。例如,变量可以引用字符串和符号,例如:

a = 'foo'
b = :bar

在 Ruby 中字符串是可变的,这意味着你可以改变它们:'foo' + 'bar' 将给出一个连接的字符串。您可以将符号视为不可变字符串,这意味着您无法更改符号::foo + :bar 会给您一个错误。最重要的是,相同的符号引用相同的对象:

a = :foo
b = :foo
a.object_id # => 538728
b.object_id # => 538728

这提高了哈希查找和其他操作的性能。

【讨论】:

我想为未来的读者指出,能够添加两个对象来取出另一个对象并不意味着该对象是可变的。 Python 和 Lua 中的字符串是不可变的;添加其中两个会给你另一个对象。在 Ruby 中,字符串是可变的,但是添加其中两个不会改变任何一个基本字符串,它会为您提供一个新的字符串对象。

以上是关于Ruby中的符号和变量有什​​么区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Ansible 角色中的默认值和变量有什​​么区别?

Docker和虚拟机有什什么区别?

Ruby 中的“\n”(换行符)和“\r”(回车符)有啥区别?

ruby中各种变量范围之间的区别

C语言里怎样理解长整型 短整型 和无符号型变量和常量?

Ruby 中的“包含模块”和“扩展模块”有啥区别? [复制]