7

final私は最初に、Javaでの匿名内部クラスで の使用についてこの質問をしました。なぜ匿名内部クラスでfinalキーワードを使用するのですか?

私は実際にMartinOderskyのScalaの本を読んでいます。Scalaは多くのJavaコードを単純化しているようですが、Scalaクロージャの場合、大きな違いに気付くことができました。

Javaでは、匿名の内部クラスを使用してクロージャを「シミュレート」し、最終変数(スタックではなくヒープ上に存在するようにコピーされます)をキャプチャしますが、Scalaでは、valをキャプチャできるクロージャを作成できるようですが、また、varであるため、クロージャ呼び出しで更新します。

finalつまり、キーワードなしでJava匿名内部クラスを使用できるようなものです。私は本を​​読み終えていませんが、今のところ、この言語デザインの選択に関する十分な情報を見つけることができませんでした。

関数の副作用を本当に処理しているように見えるMartinOderskyが、クロージャを選択して、だけでなく、valとの両方をキャプチャできるようにする理由を誰かに教えてもらえますか?varval

JavaとScalaの実装の長所と短所は何ですか?

ありがとう

関連する質問: Scalaクロージャでは、キャプチャされた変数はいつJVMヒープに存在し始めますか?

4

2 に答える 2

8

オブジェクトは、同じ環境へのアクセスを共有するクロージャーのバッグを見ることができ、その環境は通常変更可能です。では、なぜ無名関数から生成されたクロージャの能力を弱めるのでしょうか?

また、可変変数と無名関数を持つ他の言語も同じように機能します。リースの驚きの原則。Javaは、可変変数が内部クラスによってキャプチャされることを許可しないという点で、実際にはWEIRDです。

そして時々それらはただ役に立つだけです。たとえば、怠惰な処理または将来の処理の独自のバリアントを作成するための自己変更サンク。

欠点?それらには、共有された可変状態のすべての欠点があります。

于 2012-10-11T04:46:12.250 に答える
1

ここにいくつかの利点と欠点があります。

言語設計には、何かのコストがプログラマーに明らかであるべきであるという原則があります。(これはホルトのチューリング言語の設計と定義で最初に見ましたが、彼が付けた名前を忘れています。)同じように見える2つのものは同じコストになるはずです。2つのローカル変数のコストは同じである必要があります。これはJavaに有利です。Javaの2つのローカル変数は同じように実装されているため、それらの1つが内部クラスで言及されているかどうかに関係なく、コストは同じです。Javaに有利なもう1つのポイントは、ほとんどの場合、キャプチャされた変数は実際に最終的なものであるため、プログラマーが非最終的なローカル変数をキャプチャすることを妨げるコストはほとんどないということです。また、finalの主張は、すべてのローカル変数がスタック変数であることを意味するため、コンパイラーを単純化します。

言語設計には、直交するという別の原則があります。valをキャプチャできる場合は、varをキャプチャしないでください。賢明な解釈がある限り、なぜ制限を設けるのか。言語が十分に直交していないとき、それらはひねくれているように見えます。一方、直交性が多すぎる言語では、実装が複雑になる可能性があります(したがって、バグが多い、および/または遅れている、および/または少ない)。たとえば、Algol 68はスペードで直交性を持っていましたが、それを実装するのは簡単ではありませんでした。つまり、実装が少なく、取り込みもほとんどありませんでした。Pascal(ほぼ同時に設計された)には、コンパイラーの作成を容易にするあらゆる種類のエレガントでない制限がありました。その結果、多くの実装と多くの取り込みが行われました。

于 2012-10-11T03:04:44.130 に答える