当我说{ :bla => 1, :bloop => 2 }时,:到底做什么?我在什么地方读到过,它与字符串相似,但某种程度上是一个符号。
{ :bla => 1, :bloop => 2 }
:
我对这个概念不是很清楚,有人能给我一些启发吗?
:foo是一个名为“foo”的符号。符号有一个明显的特征,任何两个命名相同的符号都是相同的:
:foo
"foo".equal? "foo" # false :foo.equal? :foo # true
这使得比较两个符号非常快(因为只涉及指针比较,而不是像在字符串中那样比较所有字符),而且你不会有无数个相同符号的副本。
另外,与字符串不同,符号是不可变的。
符号是一种在ruby中表示字符串和名称的方法。
符号和字符串之间的主要区别是,相同名称的符号在ruby会话期间只在内存中存在一次。
当你需要用同一个词来表示不同的东西时,它们很有用
这是一个象征。基本上,你是说哈希的两个元素有键bla和bloop,就像你使用了字符串"bla"和"bloop"一样。但是,它们比字符串占用更少的内存,并且更容易输入。
bla
bloop
"bla"
"bloop"
如果您熟悉Java,您可能知道Java中的字符串是不可变的。Ruby中的符号在这个意义上是类似的。它们是不可变的,也就是说,任何特定符号:symbol的出现次数都只能映射到一个内存地址。因此,建议尽可能使用符号,因为这样可以优化内存使用。
:symbol
只是为了证明答案中提到的一些事情:
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?比较字符串和字符串会失败,因为它们是不同的对象,即使它们的内容相同。==比较内容,与符号等价的检查要快得多。
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秒的差异,所以我认为这是一次洗涤。
这里有一些引用自著名的书使用Rails进行敏捷Web开发,这可能有助于理解象征:
Rails使用符号来标识事物。特别地,它在命名方法参数和在哈希中查找内容时使用它们作为键。
redirect_to :action => "edit", :id => params[:id]
您可以将符号视为神奇地变成常量的字符串字面量。或者,你可以认为冒号表示“命名的东西”,所以:id是“命名为id的东西”。
如果你使用:foo => bar, foo将是一个符号。符号的好处是它们是独一无二的。当调用散列中的项时,执行hash[:foo]。
:foo => bar
hash[:foo]
符号比字符串需要更少的内存,如果你想让你的程序更快一点,它们也很有用。
puts "hello".object_id
:hello.object_id
所有这些答案都忽略了一个额外的诱人细节。如果你对符号进行字符串化: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对“赤裸的词”的回答。