私が言うとき{ :bla => 1, :bloop => 2 }
、正確には何を:
しますか?私はどこかそれが文字列にどのように似ているかについてどこかで読みましたが、どういうわけか記号です。
私はコンセプトについて明確ではありません、誰かが私を啓発できますか?
私が言うとき{ :bla => 1, :bloop => 2 }
、正確には何を:
しますか?私はどこかそれが文字列にどのように似ているかについてどこかで読みましたが、どういうわけか記号です。
私はコンセプトについて明確ではありません、誰かが私を啓発できますか?
回答:
:foo
「foo」という名前のシンボルです。シンボルには、同じ名前の2つのシンボルが同じになるという明確な機能があります。
"foo".equal? "foo" # false
:foo.equal? :foo # true
これにより、2つのシンボルの比較が非常に高速になります(文字列のようにすべての文字を比較するのではなく、ポインターの比較のみが含まれるため)。さらに、同じシンボルの膨大な数のコピーが浮遊することはありません。
また、文字列とは異なり、シンボルは不変です。
"foo".equal? "foo"
偽ですか?b)シンボルをどこでも参照できますが、基本的にはグローバル変数のようにできますか?
equal?
RubyでID比較を行います。のような各文字列リテラル"foo"
は、新しい文字列インスタンスを作成します。Rubyの文字列は変更可能であるため、このように機能します。2.シンボルはグローバルですが、シンボルには状態がないため、グローバル変数よりもグローバル定数に似ています。したがって、シンボルの使用は、グローバル変数のようにアンチパターンではありません。
"foo" == "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秒の違いしかないので、どちらを使用するかということを説明します。
==
よりも高速になり.equal?
ました。シンボル比較は、文字列比較より3+倍速くなりました。
有名な書籍「Railsを使用したアジャイルWeb開発」からの引用がいくつかあります。これは、シンボルを理解するのにも役立ちます。
Railsはシンボルを使用して物事を識別します。特に、メソッドパラメータに名前を付けたり、ハッシュで物事を調べたりするときに、それらをキーとして使用します。
redirect_to :action => "edit", :id => params[:id]
シンボルは、魔法のように定数にされた文字列リテラルと考えることができます。または、コロンを「指定されたもの」を意味すると見なすことができるため、:idは「idで指定されたもの」です。
ルビーでは、各オブジェクトは一意のオブジェクト識別子を持っていputs "hello".object_id
ます。irbに書き込んでreturnを2回押すと、2つの異なる戻り値を取得しますが、:hello.object_id
2回書き込んだ場合、同じ1つの戻り値しか取得できません。それが違いを説明しているはずです。
これらすべての答えは、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の答えです。
Javaに精通している場合は、Javaの文字列が不変であることに気付くでしょう。Rubyでもその意味でシンボルは似ています。それらは不変です。つまり、特定のシンボルの任意の数の出現は:symbol
、単一のメモリアドレスにのみマップされます。また、メモリの使用を最適化するため、可能な限りシンボルを使用することをお勧めします。
NSString
。そこ"foo"
は常に等しくなり"foo"
、内部で同じ文字列がちょうどを指摘されているので、。答えはまだ混乱を招くでしょう。