[英]What is the colon operator in Ruby?
當我說{: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
那么,將字符串與使用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 秒的差異,所以我會說這是一個可以使用的洗滌。
符號是在 ruby 中表示字符串和名稱的一種方式。
符號和字符串的主要區別在於,在 ruby 的 session 期間,同名的符號在 memory 中只存在一次。
當您需要使用相同的詞來表示不同的事物時,它們很有用
著名書籍Agile Web Development with Rails中有一些引述,這也可能有助於理解符號:
Rails 使用符號來識別事物。 特別是,它在命名方法參數和在哈希中查找內容時將它們用作鍵。
redirect_to :action => "edit", :id => params[:id]
您可以將符號視為神奇地變成常量的字符串文字。 或者,您可以認為冒號表示“命名的事物”,因此:id 是“命名為 id 的事物”。
在 ruby 中,每個 object 都有一個唯一的 object 標識符,如果你寫puts "hello".object_id
:hello.object_id
你的 irb 中並點擊返回 2 次不同的時間,你會得到 hello:.2 不同的返回值只得到相同的一個返回值。 這應該解釋了差異。
如果你使用:foo => bar
, foo 將是一個符號。 符號的好處是它們是獨一無二的。 當您調用 hash 中的項目時,您執行hash[:foo]
。
與字符串相比,符號需要更少的 memory,如果您想讓程序更快一點,它們也很有用。
所有這些答案都省略了一個額外的誘人細節..如果您將符號串起來: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 對“裸詞”的回答。
這是一個象征。 基本上,您是說 hash 的兩個元素具有鍵bla
和bloop
,就像您使用了字符串"bla"
和"bloop"
。 但是,它們占用的 memory 比字符串少,並且更易於鍵入。
如果您熟悉 Java,您可能知道 Java 中的字符串是不可變的。 Ruby 中的符號在這個意義上是相似的。 它們是不可變的,即特定符號的任意數量出現:symbol
將 map 到僅單個 memory 地址。 因此,建議盡可能使用符號,因為它優化了 memory 的使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.