当我说{:bla => 1,:bloop => 2}时,:到底做什么?我在什么地方读到过,它与字符串相似,但某种程度上是一个符号。

我对这个概念不是很清楚,有人能给我一些启发吗?


当前回答

所有这些答案都忽略了一个额外的诱人细节。如果你对符号进行字符串化: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对“赤裸的词”的回答。

其他回答

如果您熟悉Java,您可能知道Java中的字符串是不可变的。Ruby中的符号在这个意义上是类似的。它们是不可变的,也就是说,任何特定符号的出现次数:symbol将只映射到单个内存地址。因此,建议尽可能使用符号,因为这样可以优化内存使用。

这是一个象征。基本上,您说的是散列的两个元素有键bla和bloop,就像您使用了字符串“bla”和“bloop”一样。但是,它们比字符串占用更少的内存,并且更容易输入。

所有这些答案都忽略了一个额外的诱人细节。如果你对符号进行字符串化: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对“赤裸的词”的回答。

只是为了证明答案中提到的一些事情:

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)

两种符号测试在速度方面基本相同。在100万次迭代之后,只有0.004733秒的差异,所以我认为这是一次洗涤。

在ruby中,每个对象都有一个唯一的对象标识符,如果你写入“hello”。Object_id在你的irb和点击返回2次不同的,你将得到2个不同的返回值,但如果你写:hello。Object_id 2次,只能得到相同的返回值。 这应该可以解释这种差异。