Ruby中的符号

时间:2011-07-14 10:33:07

标签: ruby symbols

我不知道我是否理解符号是什么。我在不同的地方阅读以下内容:

  • 符号是不可变的,这意味着内容在初始化后不会改变。这意味着对象可以有很多引用,因为内容不能更改。
  • 将符号用于内容重要的身份和字符串。
  • 符号对象仅实例化一次,并且只要进程运行就存在。
  • 关于符号表

我不明白这些短语。最后,我不明白符号对象是什么。 :name是一个符号对象,还是:name只是对其他地方的符号对象的引用?

6 个答案:

答案 0 :(得分:4)

Eloquent Ruby”一书中引用的这句话帮助我理解符号,书中有一整章涉及字符串和符号也非常好。

答案是我们倾向于在代码中使用两个字符串而不是 不同的目的:第一个也是最明显的用于字符串的是保存一些数据 我们正在处理。从数据库中读取这些Book对象,你会非常 可能你的手里充满了字符串数据,比如书的标题,作者的 名称和实际文本。

我们使用字符串的第二种方式是在我们的代码中表示事物 克,想要找到表中所有记录的事情。关键的事情 :我们的Book ActiveRecord示例中的所有内容都是ActiveRecord可以识别它 看到它 - 代码需要知道要返回哪些记录,并且:所有都是标志 它应该返回每一个。关于使用类似的东西的好处:所有这一切 一种“代表”的职责是它对人类也有意义:你是更多 可能会识别出什么:所有这些都意味着当你遇到它而不是0,或-1,甚至 (天堂禁止!)0x29ef。

这两个用于字符串 - 用于常规数据处理任务 另一方面,对于内部的,象征性的,标记式的工作而言,另一方面 对物体的不同要求。如果您正在处理数据,您将需要拥有 触手可及的各种字符串操作工具:您可能想要第一个 标题的十个字符,或者您可能想要获取其长度或查看它是否匹配 一些正则表达式。另一方面,如果你使用一些角色来站立 对于你的代码中的某些东西,你可能不太喜欢弄乱它 实际人物。相反,在第二种情况下你只需要知道这件事 是告诉您查找所有记录或只是第一条记录的标志。主要是什么时候 你想要一些角色代表什么,你只需要知道这是不是 同样,快速,可靠。

答案 1 :(得分:3)

也许这个IRB会议可以解决一些问题:

irb(main):001:0> "First".object_id
=> 23849064
irb(main):002:0> "First".object_id
=> 23842248
irb(main):003:0> "First".object_id
=> 23835432
irb(main):004:0> "First".object_id
=> 23828616
irb(main):005:0> :First.object_id
=> 301892
irb(main):006:0> :First.object_id
=> 301892
irb(main):007:0> :First.object_id
=> 301892
irb(main):008:0> :First.object_id
=> 301892
irb(main):009:0>

想象一下object_id方法与对象的地址类似。如您所见,“First”字符串每次都有不同的地址(意味着每次都创建一个新对象),而符号不会改变。也许你可以将符号与单例相关联(如单例模式,而不是元编程方式),以便于理解。

答案 2 :(得分:2)

您可以将符号视为一种常量,但不包含实际值。在没有符号的语言中,为方便起见,您可能会这样做:

const BLUE = 1
const GREEN = 2

my_color = GREEN

...


if (my_color == GREEN)

在Ruby中,您可以使用符号:

my_color = :green

...

if my_color == :green

它更高效,因为符号只是一个符号。它不存储值或任何内容,因此您不需要初始化它们。我不确定Ruby解释器中的符号是如何处理的,但我认为这对任何新手ruby程序员都不相关。

可在此处找到一份好的指南:http://www.troubleshooters.com/codecorn/ruby/symbols.htm

答案 3 :(得分:1)

我认为符号最好通过用例来解释。

对于创建常量,它们比整数更具表现力。

def rgb(color_symbol)
  return nil unless color_symbol.is_a? Symbol
  case color_symbol
  when :red;   { r: 255, g: 0, b: 0 }
  when :green; { r: 0, g: 255, b: 0 }
  when :blue;  { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_symbol= :red)

更具可读性
def rgb(color_number)
  return nil unless color_number.is_a? Fixnum
  case color_number
  when 1; { r: 255, g: 0, b: 0 }
  when 2; { r: 0, g: 255, b: 0 }
  when 3; { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_number= 2)

对于条件语句中的比较,符号只是通过它们的唯一地址进行比较,因此它们比字符串更有效,字符串按长度和每个字符进行比较。

def rgb(color_string)
  return nil unless color_string.is_a? String
  case color_string
  when "red";   { r: 255, g: 0, b: 0 }
  when "green"; { r: 0, g: 255, b: 0 }
  when "blue";  { r: 0, g: 0, b: 255 }
  else; { r: 0, g: 0, b: 0 }
  end
end

p rgb(color_string= "blue")

这比使用符号效率低。

答案 4 :(得分:0)

这篇文章也很有用http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/,因为它帮助我理解符号与字符串的区别。

答案 5 :(得分:0)

Symbol实例是一组有序的字符。 String实例是字符的容器,可以包含任何字符序列的位置。