15

First time I tried learning Ruby was 2 years ago, now I have started again. The reason I stopped was because I could not understand the Symbol class. And now I am at the same point again, completely lost in when and why you use Symbols. I have read the other posts on Stackoverflow as well as Googled for several explanations. But I do not understand it yet.

First I thought symbols was just a way to create some sort of "named constant" without having to go through the same process as in let say Java.

:all 

instead of making a constant with an arbitrary value public static final String ALL = 8;

However it does not make much sense when you use it in e.g. attr_accessor :first_name etc. Are Symbols just a lightweight String class? I am having problems understanding how I should interpret, when and how to use symbols both in my own classes and in frameworks.

4

5 に答える 5

34

つまり、シンボル軽量の文字列ですが、不変でガベージ コレクションの対象外でもあります。

データ処理タスクでそれらを不変の文字列として使用しないでください(シンボルが作成されると、破棄できないことに注意してください)。通常、ものに名前を付けるために記号を使用します。

# typical use cases

# access hash value
user = User.find(params[:id])

# name something
attr_accessor :first_name

# set hash value in opts parameter
db.collection.update(query, update, multi: true, upsert: true)  

最初の例を見てみましょうparams[:id]。適度に大きな Rails アプリでは、コードベースの周りに何百、何千ものものが散らばっているかもしれません。その値に文字列 でアクセスした場合params["id"]、それは毎回新しい文字列が割り当てられることを意味します (その文字列は後で収集する必要があります)。シンボルの場合、実際にはどこでも同じシンボルです。メモリ アロケーター、ガベージ コレクター、さらにはユーザーの作業が少なくなります (:よりも入力が高速です"") 。

コードに頻繁に現れる単純な 1 語の文字列があり、それに対して特殊なこと (補間、gsub、upcase など) を行っていない場合は、シンボルの候補として適している可能性があります。

ただし、これは、名前付けなどの実際のプログラムロジックの一部として使用されるテキストにのみ適用されますか?実際にプログラムを実行しているときに取得するテキストではありません...ユーザー/Web などからのテキストなど?

データをユーザー/Webからシンボルに変換したいという単一のケースは考えられません(コマンドラインオプションの解析を除いて)。主にその結果のためです(一度作成されたシンボルは永遠に存続します)。

また、多くのエディターは、コード内でシンボルを強調するために、シンボルにさまざまな色を付けています。この例を見てください

シンボルと文字列

于 2012-07-12T08:09:53.257 に答える
12

The O'Reilly Ruby Cookbook (p. 15) は、Jim Weirich の次の言葉を引用しています。

  • オブジェクトの内容 (文字のシーケンス) が重要な場合は、文字列を使用します。
  • オブジェクトの識別が重要な場合は、シンボルを使用してください。

重要なのはキーのIDであるため、シンボルは一般にハッシュ キーとして使用されます。Object#sendなどの特定のメソッドを使用してメッセージを渡す場合にも、シンボルが必要です。

于 2012-07-14T23:57:27.773 に答える
8

通常、Ruby の実装には、すべてのクラス、メソッド、および変数の名前を格納するテーブルがあります。テーブル内の位置によってメソッド名を参照し、コストのかかる文字列比較を回避します。ただし、このテーブルも使用して値を追加できます: symbols.

文字列をテキスト コンテンツではなく識別子として使用するコードを記述する場合は、シンボルを検討してください。引数が 'male' または 'female' であることを期待するメソッドを作成する場合は、 and の使用:maleを検討して:femaleください。2 つのシンボルが等しいかどうかを比較することは、文字列よりも高速です (これが、シンボルが適切なハッシュ キーを作成する理由です)。

于 2012-07-12T13:54:00.093 に答える
5

シンボルは、言語で名前を付けるために使用されます。クラスの名前、メソッドの名前などです。これらは文字列に非常に似ていますが、ガベージ コレクションが行われないことと、等しいかどうかのテストが非常に高速になるように最適化されています。

Java 実装は、実行時に使用できないことを除いて、非常に似ています。つまり、 のような Java コードを記述するとobj.someMethod(4)、文字列 'someMethod' がコンパイラによってシンボルに変換され、.class ファイルのルックアップ テーブルに埋め込まれます。これらのシンボルは、ガベージ コレクションされない「特別な」文字列のようなものであり、等しいかどうかの比較が非常に高速です。これは、Ruby とほぼ同じですが、Ruby では実行時に新しいシンボルを作成できるのに対し、Java ではコンパイル時にしか作成できないという点が異なります。

これは、新しいメソッドを作成するのと同じです。Java ではコンパイル時にそれが可能です。Ruby は実行時にそれを許可します。

于 2012-07-17T10:38:28.340 に答える