これは、この質問の逆です。Javaと.NETで文字列を変更できないのはなぜですか。
この選択は、操作(追加など)が可変文字列で効率的であるという理由だけでRubyで行われたのですか、それとも他の理由がありましたか?
(効率だけの場合、Rubyの設計は効率的な実装の促進に高い重点を置いていないように見えるので、それは独特に思えます。)
これは、この質問の逆です。Javaと.NETで文字列を変更できないのはなぜですか。
この選択は、操作(追加など)が可変文字列で効率的であるという理由だけでRubyで行われたのですか、それとも他の理由がありましたか?
(効率だけの場合、Rubyの設計は効率的な実装の促進に高い重点を置いていないように見えるので、それは独特に思えます。)
ご存知のように、これはRubyの設計と一致しています。不変の文字列は、可変の文字列よりも効率的です(文字列が再利用されるため、コピーが少なくなります)が、プログラマーの作業は困難になります。文字列を変更可能と見なすのは直感的です。文字列を連結することができます。これに対処するために、Java+
は2つの文字列の連結を(を介して)StringBufferオブジェクトの使用にサイレントに変換し、他にもそのようなハックがあると確信しています。Rubyは代わりに、パフォーマンスを犠牲にして文字列をデフォルトで可変にすることを選択します。
String#upcase!
Rubyには、文字列が可変であることに依存するなど、多くの破壊的なメソッドもあります。
もう1つの考えられる理由は、RubyがPerlに触発されており、Perlがたまたま可変文字列を使用していることです。
RubyにはSymbolsとfrozenStringsがあり、どちらも不変です。追加のボーナスとして、シンボルは可能な文字列値ごとに一意であることが保証されています。
これらは私の意見であり、マッツの意見ではありません。この回答の目的で、言語に「不変の文字列」があると言うとき、それはすべての文字列が不変であることを意味します。つまり、可変の文字列を作成する方法はありません。
「不変の文字列」設計では、文字列を識別子(たとえば、ハッシュキーやその他のVM内部での使用)とデータストレージ構造の両方と見なします。。識別子が変更可能になるのは危険だという考えです。私には、これは単一責任の違反のように聞こえます。Rubyには識別子の記号があるので、文字列は自由にデータストアとして機能します。Rubyが文字列をハッシュキーとして許可しているのは事実ですが、プログラマーが文字列を変数に格納し、それをハッシュキーとして使用してから、文字列を変更することはめったにないと思います。プログラマーの心の中では、文字列の2つの使用法の分離があります(またはそうあるべきです)。多くの場合、ハッシュキーとして使用される文字列はリテラル文字列であるため、変更される可能性はほとんどありません。文字列をハッシュキーとして使用することは、2つの文字列の配列をハッシュキーとして使用することと大差ありません。キーとして何を使っているのかを頭の中でしっかり把握していれば問題ありません。
文字列をデータストアとして持つことは、認知の単純さの観点から有用です。Javaとそのを考えてみてStringBuffer
ください。これは、ある文字列を別の文字列の特定のインデックスに挿入するなどの文字列操作を実行しようとしている場合に管理する必要がある追加のデータ構造です(すでに大きく、多くの場合直感的でない標準ライブラリにあります)。そのため、Javaはこの種の操作の必要性を認識していますが、不変の文字列はプログラマーに公開されているため、別の構造を導入する必要がありました。これにより、車輪の再発明を行わなくても操作が可能になります。これにより、プログラマーに余分な認知的負荷がかかります。
Pythonでは、挿入する最も簡単な方法は、挿入ポイントの前後のサブ文字列を取得し、挿入される文字列の周囲にそれらを連結することです。新しい文字列を挿入して返すメソッドを標準ライブラリに簡単に追加できると思います。ただし、メソッドが呼び出された場合insert
、初心者はそれが文字列を変更すると考えるかもしれません。説明的であるためには、それは呼ばれるnew_with_inserted
か、そのような奇妙なものでなければなりません。日常の使用では、「挿入」とは、挿入されたものの内容を変更することを意味します(たとえば、メールボックスに封筒を挿入すると、メールボックスの内容が変更されます)。繰り返しになりますが、これにより、「データストアを変更できないのはなぜですか」という疑問が生じます。
Rubyはオブジェクトのフリーズを提供するため、微妙なバグを発生させることなくオブジェクトを安全に渡すことができます。良い点は、Rubyが文字列を他のデータ構造(配列、ハッシュ、クラスインスタンス)と同じように扱うことです。それらはすべて凍結することができます。一貫性はプログラマーにとって使いやすいものです。不変の文字列は、データストアとして使用する場合、実際にはそうではない場合でも、文字列を「特別な」データ構造として際立たせます。