{ :bla => 1, :bloop => 2 }
と言うとき、:
は正確に何をしますか?私はどこか文字列に似ているが、どういうわけか記号について読んだ。
私はコンセプトについてあまり明確ではありませんが、誰かが私を啓発できますか?
:foo
は「foo」という名前のシンボルです。シンボルには、同じ名前の2つのシンボルが同一であるという明確な機能があります。
"foo".equal? "foo" # false
:foo.equal? :foo # true
これにより、2つのシンボルの比較が非常に高速になります(文字列のようにすべての文字を比較するのではなく、ポインターの比較のみが関係するため)。また、同じシンボルのコピーが無数にありません。
また、文字列とは異なり、シンボルは不変です。
答えで言及されていることのいくつかを示すためだけに
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のセッション中に一度だけメモリに存在することです。
同じWordを使用して異なるものを表す必要がある場合に便利です。
symbolも理解するのに役立つかもしれない有名な本 RailsでのアジャイルWeb開発 からの引用があります:
Railsは、シンボルを使用して物事を識別します。特に、メソッドのパラメーターに名前を付け、ハッシュで物事を調べるときにキーとして使用します。
redirect_to :action => "edit", :id => params[:id]
シンボルは、魔法のように定数にされた文字列リテラルと考えることができます。または、コロンは「名前が付けられたもの」を意味すると考えることができます。したがって、:idは「名前が付けられたもの」です。
Rubyでは、各オブジェクトに一意のオブジェクト識別子があり、puts "hello".object_id
をirbに書き込んで2回異なるリターンを押すと、2つの異なる戻り値を取得しますが、:hello.object_id
を2回書き込むと、同じ値を返します。それが違いを説明しているはずです。
:foo => bar
を使用する場合、fooはシンボルになります。シンボルの利点は、シンボルが一意であることです。ハッシュ内のアイテムを呼び出すと、hash[:foo]
を実行します。
シンボルは文字列よりもメモリを必要としないため、プログラムを少し速くしたい場合にも役立ちます。
これらのすべての答えは、1つの余分な食欲をそそる詳細を省略します。シンボル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の答えです。
それはシンボルです。基本的に、ハッシュの2つの要素にはキーbla
とbloop
があり、文字列"bla"
と"bloop"
を使用したかのように言っています。ただし、文字列よりもメモリを消費せず、入力しやすいです。