Ruby中的符号和变量有什​​么区别?

Cu1*_*ure 11 ruby variables symbols ruby-on-rails

我试图理解符号和红宝石中的变量之间的区别.在给出引用对象的名称时,它们似乎完全相同.

我已经读过这些符号可用于更快的程序,但我不确定它们为什么或如何以任何方式与变量不同.

tad*_*man 13

符号是一个"内化"字符串,它更像是一个常数而不是任何东西.典型例子:

account_details = {
  :name => 'Bob',
  :age => 20
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

相比:

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

:string.object_id == :string.object_id
# => true
Run Code Online (Sandbox Code Playgroud)

即使这两个字符串相同,它们也是独立的字符串对象.当用作哈希,方法参数和其他常见情况的键时,这些对象会很快混乱你的内存并进行大量复制,除非你不想使用相同的字符串实例.符号会自动为您执行此操作.

  • `attr_accessor:example`的意思是"定义一个名为'example'的读/写属性",并定义方法`example`和example =`以及实例变量`@example`.参数作为符号传递,因此接收方法可以告诉它是什么.请记住,变量名是本地的,变量的名称永远不会传入."attr_reader example"表示"创建一个带有任何变量的读者*example*想要它被调用".`attr_reader`函数无法知道变量的名称.这里的关系是用于传达所需名称的符号. (2认同)

mip*_*adi 5

他们非常不同。变量给对象贴上标签。符号更像字符串,只不过它们是不可变的并且驻留在内存中,因此对同一符号的多次引用不会使用额外的内存。(将此与字符串进行对比,其中对同一字符串的多次引用将导致该字符串的多个副本。)


Dan*_*Dan 5

变量包含对象的引用.例如,变量可以引用字符串和符号,如:

a = 'foo'
b = :bar
Run Code Online (Sandbox Code Playgroud)

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

a = :foo
b = :foo
a.object_id # => 538728
b.object_id # => 538728
Run Code Online (Sandbox Code Playgroud)

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

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