Ruby中的冒号运算符是什么?

时间:2011-06-14 00:30:01

标签: ruby symbols

当我说{ :bla => 1, :bloop => 2 }时,:究竟做了什么?我在某处读到了它与字符串的相似之处,但不知何故是一个符号。

我对这个概念不是很清楚,有人可以启发我吗?

9 个答案:

答案 0 :(得分:239)

:foo是一个名为“foo”的符号。符号具有明显的特征,即任何两个名称相同的符号都是相同的:

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

这使得比较两个符号的速度非常快(因为只涉及指针比较,而不是像比较字符串中的所有字符),而且你不会有相同符号浮动的无数副本。

此外,与字符串不同,符号是不可变的。

答案 1 :(得分:44)

只是为了演示答案中提到的一些内容:

require 'benchmark'

n = 1_000_000

print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo"     -> ', ("foo" == "foo"    ), "\n"
print ':foo.equal? :foo   -> ', (:foo.equal? :foo  ), "\n"
print ':foo == :foo       -> ', (:foo == :foo      ), "\n"

Benchmark.bm(10) do |b|
  b.report('string')     { n.times { "foo".equal? "foo" }}
  b.report('str == str') { n.times { "foo" == "foo"     }}
  b.report('symbol')     { n.times { :foo.equal? :foo   }}
  b.report('sym == sym') { n.times { :foo == :foo       }}
end

运行输出:

"foo".equal? "foo" -> false
"foo" == "foo"     -> true
:foo.equal? :foo   -> true
:foo == :foo       -> true

因此,使用equal?将字符串与字符串进行比较会失败,因为它们是不同的对象,即使它们是相同的内容。 ==比较内容,使用符号的等效检查要快得多。

                 user     system      total        real
string       0.370000   0.000000   0.370000 (  0.371700)
str == str   0.330000   0.000000   0.330000 (  0.326368)
symbol       0.170000   0.000000   0.170000 (  0.174641)
sym == sym   0.180000   0.000000   0.180000 (  0.179374)

两种符号测试基本上与速度相同。经过1,000,000次迭代后,只有0.004733秒的差异,所以我说这是一个可以使用的清洗。

答案 2 :(得分:30)

符号是一种在ruby中表示字符串和名称的方法。

符号和字符串之间的主要区别在于,在ruby会话期间,初始化了同名符号并且只在内存中存在一次。

当您需要使用相同的词来表示不同的内容时,它们非常有用

答案 3 :(得分:16)

着名的书籍Agile Web Development with Rails中有一些引用,这可能有助于理解符号

  

Rails使用符号来识别事物。特别是,它在命名方法参数和在哈希中查找时将它们用作键。

redirect_to :action => "edit", :id => params[:id]
  

您可以将符号视为神奇地制作为常量的字符串文字。或者,您可以将冒号视为“名为”的东西,因此:id是“名为id的东西”。

答案 4 :(得分:4)

在ruby中,每个对象都有一个唯一的对象标识符,如果你在你的irb中写puts "hello".object_id并点击返回2个不同的时间,你会得到2个不同的返回值,但如果你写:hello.object_id 2时间你只会获得相同的返回值。 这应该解释了差异。

答案 5 :(得分:2)

如果您使用:foo => bar,则foo将是一个符号。符号的好处是它们是独一无二的。当您调用哈希中的项目时,您执行hash[:foo]

符号需要的内存少于字符串,如果你想让你的程序更快一点,这也会有用。

答案 6 :(得分:0)

这是一个象征。基本上,您说哈希的两个元素具有键blabloop,就像您使用了字符串"bla""bloop"一样。但是,它们占用的内存少于字符串,并且更容易键入。

答案 7 :(得分:0)

所有这些答案都省略了一个诱人的细节..如果您将符号:foo字符串化,则会得到..猜怎么着。字符串“ foo”。因此

irb(main):025:0>
irb(main):026:0> :foo
=> :foo
irb(main):027:0> "#{:foo}"
=> "foo"
irb(main):028:0>
irb(main):029:0> 'foo' <=> :foo
=> nil
irb(main):030:0> 'foo' <=> :foo.to_s
=> 0
irb(main):031:0>

因此,..对于Perl程序员..这是Ruby对“裸词”的回答。

答案 8 :(得分:-1)

如果您熟悉Java,您可能会意识到Java中的字符串是不可变的。在Ruby中,符号在这个意义上是相似的。它们是不可变的,即,特定符号:symbol的任何数量的出现将仅映射到单个存储器地址。因此,建议尽可能使用符号,因为它可以优化内存使用。