问题描述
|
当我说
{ :bla => 1,:bloop => 2 }
时,:
到底是做什么的?我在某处读到了它与字符串的相似之处,但在某种程度上却是一个符号。
我对这个概念不太清楚,有人可以启发我吗?
解决方法
:foo
是一个名为\“ foo \”的符号。符号具有鲜明的特征,即任何两个相同的符号将是相同的:
\"foo\".equal? \"foo\" # false
:foo.equal? :foo # true
这使得比较两个符号的速度非常快(因为只涉及指针比较,而不是像字符串中那样比较所有字符),而且您不会在同一符号上成千上万个副本。
另外,与字符串不同,符号是不可变的。
, 只是为了演示答案中提到的一些内容:
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
因此,使用ѭ6using将字符串与字符串进行比较失败,因为它们是不同的对象,即使它们的内容相同。 ==
比较内容,带符号的等效检查要快得多。
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秒,因此我认为这是一次洗礼。
, 符号是用红宝石表示字符串和名称的一种方式。
符号和字符串之间的主要区别在于,同名符号被初始化,并且在一个红宝石会话期间仅在内存中存在一次。
当您需要使用相同的单词表示不同的事物时,它们很有用
, 著名的书《用Rails进行Web敏捷开发》中有一些引文,也可能有助于理解该符号:
Rails使用符号来识别事物。特别是,在命名方法参数并在哈希中查找内容时,它将它们用作键。
redirect_to :action => \"edit\",:id => params[:id]
您可以将符号视为神奇地制成常量的字符串文字。另外,您可以考虑冒号是指“名称为”的事物,因此:id是“名称为”的事物。
, 在ruby中,每个对象都有一个唯一的对象标识符,如果在irb中写入puts \"hello\".object_id
并两次击中return,您将获得2个不同的返回值,但是如果您写入:hello.object_id
2次,您将仅获得相同的返回值。
那应该解释了差异。
, 如果使用:foo => bar
,则foo将成为符号。符号的好处是它们是唯一的。当您调用哈希中的项目时,您将执行hash[:foo]
。
符号比字符串需要更少的内存,如果要使程序更快一点,这也使它们很有用。
, 这是一个象征。基本上,您是说哈希的两个元素具有键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对“裸词”的回答。
, 如果您熟悉Java,您可能会知道Java中的字符串是不可变的。在Ruby中,符号在这方面是相似的。它们是不可变的,即,任何特定符号“ 19”的出现次数都将映射到单个存储器地址。因此,建议尽可能使用符号,因为它可以优化内存使用率。