回答:
Java用語では、シンボルはインターンされた文字列です。つまり、たとえば、参照の等価比較(eq
Scalaと==
Java)は、通常の等価比較(==
Scalaとequals
Java)と同じ結果に'abcd eq 'abcd
なります。trueを返しますが、"abcd" eq "abcd"
JVMの気まぐれによっては(true リテラル用ですが、一般的に動的に作成される文字列用ではありません)。
シンボルを使用する他の言語には、Lisp('abcd
Scalaのように使用)、Ruby(:abcd
)、Erlang、Prolog(abcd
;シンボルの代わりにアトムと呼ばれます)があります。
文字列の構造を気にせず、純粋に何かの名前として使用する場合は、シンボルを使用します。たとえば、CDを表すデータベーステーブルがあり、 "price"という名前の列が含まれている場合、 "price"の2番目の文字が "r"であることや、列名の連結については気にしません。そのため、Scalaのデータベースライブラリは、テーブル名と列名に記号を適切に使用できます。
コード内でsayメソッド名を表すプレーンな文字列があり、それが渡される可能性がある場合は、物事を適切に伝えていません。これは一種のデータ/コード境界の問題であり、常に線を引くのは簡単ではありませんが、その例でこれらのメソッド名がデータよりもコードであると言う場合、それを明確に識別するために何かが必要です。
シンボルリテラルが機能し、コードで使用されている構造を持つ古い文字列データのみを明確に区別します。表示したい場所に本当にあります。これは単なる文字列データではなく、実際にはコードの一部です。IDEのようなものであるという考えは、それを異なる方法で強調表示し、ツールが与えられれば、テキスト検索/置換を行うのではなく、それらをリファクタリングできます。
このリンクはそれをかなりよく議論します。
Python は、すべての変数、関数、モジュールなどの名前を持つ「インターンされた文字列」の内部グローバルテーブルを保持します。このテーブルを使用すると、インタープリターはより高速な検索と最適化を行うことができます。intern
関数を使用してこのプロセスを強制できます(sys.intern
python3)。
また、JavaとScalaは、検索を高速化するために「インターン文字列」を自動的に使用します。scalaでは、intern
メソッドを使用して文字列のインターンを強制できますが、このプロセスはすべての文字列で機能するわけではありません。シンボルはインターンされることが保証されていることから利益を得ます。そのため、単一の参照等価チェックは、等価または不等価を証明するのに十分です。