Rubyのコロン演算子とは何ですか?


234

私が言うとき{ :bla => 1, :bloop => 2 }、正確には何を:しますか?私はどこかそれが文字列にどのように似ているかについてどこかで読みましたが、どういうわけか記号です。

私はコンセプトについて明確ではありません、誰かが私を啓発できますか?



7
これを見てみてください:Ruby_Newbie Symbols Guide
Hengjie

このビデオでは、シンボルについて知っておくべきことをすべて説明しています。
totymedli

回答:


249

:foo「foo」という名前のシンボルです。シンボルには、同じ名前の2つのシンボルが同じになるという明確な機能があります。

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

これにより、2つのシンボルの比較が非常に高速になります(文字列のようにすべての文字を比較するのではなく、ポインターの比較のみが含まれるため)。さらに、同じシンボルの膨大な数のコピーが浮遊することはありません。

また、文字列とは異なり、シンボルは不変です。


2
なぜリテラル文字列が文字列のインターンをサポートしないのか疑問に思いますか
onmyway133 2014

5
@ onmyway133 Rubyの文字列は変更可能なため。インターンは不変の値にのみ適用されます。
Chris Jester-Young

3
a)なぜ"foo".equal? "foo"偽ですか?b)シンボルをどこでも参照できますが、基本的にはグローバル変数のようにできますか?
Arc676、2016

2
@ Arc676 1. equal?RubyでID比較を行います。のような各文字列リテラル"foo"は、新しい文字列インスタンスを作成します。Rubyの文字列は変更可能であるため、このように機能します。2.シンボルはグローバルですが、シンボルには状態がないため、グローバル変数よりもグローバル定数に似ています。したがって、シンボルの使用は、グローバル変数のようにアンチパターンではありません。
Chris Jester-Young

2
@ Arc676 "foo" == "foo"#=> true
Filip Bartuzi

44

答えで言及されていることのいくつかを示すためだけに:

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+倍​​速くなりました。
melvynkim 2014年

33

シンボルは、ルビで文字列と名前を表す方法です。

シンボルと文字列の主な違いは、同じ名前のシンボルが初期化され、rubyのセッション中に一度だけメモリに存在することです。

異なるものを表すために同じ単語を使用する必要がある場合に役立ちます


19

有名な書籍「Railsを使用したアジャイルWeb開発」からの引用がいくつかあります。これは、シンボルを理解するのにも役立ちます。

Railsはシンボルを使用して物事を識別します。特に、メソッドパラメータに名前を付けたり、ハッシュで物事を調べたりするときに、それらをキーとして使用します。

redirect_to :action => "edit", :id => params[:id]

シンボルは、魔法のように定数にされた文字列リテラルと考えることができます。または、コロンを「指定されたもの」を意味すると見なすことができるため、:idは「idで指定されたもの」です。


5

ルビーでは、各オブジェクトは一意のオブジェクト識別子を持っていputs "hello".object_idます。irbに書き込んでreturnを2回押すと、2つの異なる戻り値を取得しますが、:hello.object_id2回書き込んだ場合、同じ1つの戻り値しか取得できません。それが違いを説明しているはずです。


基本的に、コロン演算子は記号
Cesar Jr Rodriguez

2

を使用すると:foo => bar、fooがシンボルになります。記号の利点は、記号が一意であることです。ハッシュ内のアイテムを呼び出すときは、行いますhash[:foo]

シンボルはメモリよりも必要なメモリが少ないため、プログラムをもう少し速くしたい場合にも役立ちます。


0

それはシンボルです。基本的に、ハッシュの2つの要素にはキーblaとがありbloop、文字列"bla"とを使用した場合と同じです"bloop"。ただし、これらは文字列よりもメモリの使用量が少なく、入力も簡単です。


0

これらすべての答えは、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の答えです。


-1

Javaに精通している場合は、Javaの文字列が不変であることに気付くでしょう。Rubyでもその意味でシンボルは似ています。それらは不変です。つまり、特定のシンボルの任意の数の出現は:symbol、単一のメモリアドレスにのみマップされます。また、メモリの使用を最適化するため、可能な限りシンボルを使用することをお勧めします。


1
シンボルは不変であるという事実により、アプリケーション全体で常に同じインスタンスであり、したがって同じオブジェクトであることが保証されます。これらの参照を確認してください:troubleshooters.com/codecorn/ruby/symbols.htmは robertsosinski.com/2009/01/11/... は、Google場合は、より多くの負荷を見つけることができます。
Dhruva Sagar 2012

私はあなたがJavaにたとえていることについて話しています。Java文字列はシンボルに似ていません。Java文字列リテラルはすべての文字列ではありません。
smartnut007 2012

おそらく私の発言は十分に明確ではありませんでした。それらは不変であるという事実に関してのみ互いに​​類似しています。
Dhruva Sagar 2012

@DhruvaSagar:Objective Cを使用すると、類推はより良くなりますNSString。そこ"foo"は常に等しくなり"foo"、内部で同じ文字列がちょうどを指摘されているので、。答えはまだ混乱を招くでしょう。
Rafael Bugajewski、2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.