web-dev-qa-db-ja.com

Rubyの文字列とシンボルの違いは何ですか?

Ruby)の文字列と記号の違いは何ですか?また、どちらを使用する必要があるのですか?

59
Readonly

主な違いは、単一の値を表す複数のシンボルは同じですが、これは文字列には当てはまりません。例えば:

irb(main):007:0> :test.object_id
=> 83618
irb(main):008:0> :test.object_id
=> 83618
irb(main):009:0> :test.object_id
=> 83618

これらは:testへの3つの参照であり、すべて同じオブジェクトです。

irb(main):010:0> "test".object_id
=> -605770378
irb(main):011:0> "test".object_id
=> -605779298
irb(main):012:0> "test".object_id
=> -605784948

これらは文字列「test」への3つの参照ですが、すべて異なるオブジェクトです。

つまり、アプリケーションによっては、シンボルを使用することでメモリを節約できる可能性があります。シンボルが同じオブジェクトであるため、等しいかどうかを比較する方が高速です。オブジェクトIDだけではなく文字列値を比較する必要があるため、同一の文字列の比較ははるかに遅くなります。

いつ使用するかというと、私は通常、文字列ではなく一意の識別子が本当に必要なハッシュキーなどを除いて、ほとんどすべての文字列を使用します。

76
Robert Gamble

シンボルと文字列の違いは何ですか?

  1. シンボルは不変です。値は一定のままです。
  2. 同じシンボルの複数回の使用は同じオブジェクトIDを持ち、一意のオブジェクトIDを持つ別のオブジェクトである文字列と比較すると、常に同じオブジェクトです。
  3. SymbolsでsplitのようなStringメソッドを呼び出すことはできません。

From Rubyのシンボルと文字列の違いを理解する

中国語なら 理解Ruby Symbol も読めます。

12
Feuda

ステートメント:

foo = "bar"

メモリに新しいオブジェクトを作成します。ステートメントを繰り返す場合:

foo = "bar"

別のオブジェクトを作成します。

それをより明確に理解するには、IRBでこのコードを試してください:

foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"
foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"

次のような出力が得られます。

string bar with object id = 70358547221180
string bar with object id = 70358548927060

これは、同じ文字列に対して2つの異なるオブジェクトがあることを明確に示しています。これで、シンボルを使用するとシンボルごとに1つのオブジェクトが作成されます。

foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"
foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"

ショー:

symbol bar with object id = 7523228
symbol bar with object id = 7523228

つまり、:barのオブジェクトは1つだけです。

さらに、Symbolsはimmutableであり、SymbolsでupcasesplitなどのStringメソッドを呼び出すことはできません。

シンボルの比較は、文字列の比較よりも高速です。シンボルは、ヒープ上のメモリポインタに効果的に変換される一意のセットを形成する定数/不変文字列と考えることができます。これは、2つの整数(メモリポインタ)を比較するだけなので、2つのシンボルの比較が高速であることを意味します。

文字列は変更可能なので、ヒープ上の値へのメモリポインタは変更後に変更できます。つまり、意味的に同等な重複が存在する可能性があるため、比較操作が遅くなります。

値が一定であることが確実な場合は、シンボルを使用してください。たとえば、ハッシュキーにシンボルを使用します。値を変更する場合、または文字列メソッドを使用する場合は、文字列を使用します。

5
Nitin9791

StringSymbolのもう1つの違いは、Stringには文字列操作用のメソッドが多数あるのに対し、Symbolは比較的リーンなオブジェクトです。 。

String classSymbol class のドキュメントを確認してください。

3
Grant Hutchins

シンボルが災害になるケース。 Railsコントローラ)にparams.map(&:to_sym)があるとします。ここで、何らかの理由でユーザーから提供されたデータをシンボルに変換している場合、危険な場合があります。ユーザーから提供されたデータが大きすぎるため、シンボルがガベージコレクタではないことがわかっているため、サーバーのメモリを使い果たしてWebサイトを停止させる可能性があります。

1
Chimed Palden

Rubyの文字列とシンボルには、主に2つの違いがあります。

  1. 文字列は変更可能であり、記号は変更できません:

    • 文字列は変更可能であるため、どこかで変更される可能性があり、結果が正しくない可能性があります。
    • シンボルは不変です。
  2. 文字列はオブジェクトなので、メモリ割り当てが必要です

    puts "abc".object_id # 70322858612020
    puts "abc".object_id # 70322846847380
    puts "abc".object_id # 70322846815460
    

    一方、Symbolは同じオブジェクトを返します。

    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    

したがって、文字列はシンボルよりも使用および比較に時間がかかります。

詳細については、「 The = The Difference Between Ruby Symbols and Strings "」を参照してください。

1
Leo Le

シンボルは不変で、文字列は変更可能です。

文字列に対して何らかの操作を実行すると、新しいオブジェクトが作成され、メモリが使用されます。文字列に対してより多くの操作を実行すると、より多くのメモリを消費することになります。

シンボルは不変のオブジェクトであり、操作を実行すると元のオブジェクトに変更が加えられます。オブジェクトは作成されないため、収益性が高くなります。

詳細については、次のことができます ここをクリック

0
user3423263

文字列は可変であり、シンボルは不変である
注:変更可能なオブジェクトは割り当て後に変更できますが、不変のオブジェクトは上書きのみ可能です http://www.robertsosinski.com/2009/01/11/the-difference-between-Ruby-symbols -and-strings /

0
Nitesh

シンボルは、名前と文字列を表すために使用するものです。文字列を数回使用する必要がある場合は、シンボルを使用する方がはるかに簡単で生産的です。

そして、これはグーグルを介してこれを見つけました、より詳細を提供するかもしれません: ここに行く

0
websch01ar

記号と文字列は完全に異なります この投稿 は違いを少し洞察しています。いつ、どこでそれらを使用するかについては、このテーマに関するかなり広範囲にわたる投稿があります has many:through

0
Codebeef

対抗点として、私の友人は最近 「Ruby Rant」というタイトルの投稿 を書きました。これはRuby記号をもう一度見ます。

0
Greg Hewgill