7

私は Scala を初めて使用し、Scala ではすべてがオブジェクトであるとよく耳にします。私が得られないのは、「すべてがオブジェクトである」ことの利点は何ですか? すべてがオブジェクトでないとできないことは何ですか? 例は大歓迎です。ありがとう

4

5 に答える 5

4

「すべて」をオブジェクトにする利点は、抽象化が壊れるケースがはるかに少ないことです。

たとえば、メソッドは Java のオブジェクトではありません。文字列が 2 つあれば

String s1 = "one";
String s2 = "two";
static String caps(String s) { return s.toUpperCase(); }
caps(s1);  // Works
caps(s2);  // Also works

そのため、何かを大文字にする操作で文字列のアイデンティティを抽象化しました。しかし、操作のアイデンティティを抽象化したい場合、つまり、別の String を返す String に対して何かを行うが、詳細を抽象化したい場合はどうすればよいでしょうか? Java ではメソッドはオブジェクトではないため、行き詰まりました。

Scala では、メソッドをオブジェクトであるfunctionsに変換できます。例えば:

def stringop(s: String, f: String => String) = if (s.length > 0) f(s) else s
stringop(s1, _.toUpperCase)
stringop(s2, _.toLowerCase)

これで、空でない文字列に対して何らかの文字列変換を実行するというアイデアが抽象化されました。

また、必要に応じて、操作などのリストを作成して渡すことができます。

それほど重要でないケース (オブジェクトとクラス、プリミティブと非クラス、値クラスなど) は他にもありますが、大きなケースはメソッドとオブジェクトの区別を崩壊させて、機能の受け渡しと抽象化が受け渡しと同じくらい簡単になるようにすることです。データの周りと抽象化。

于 2013-03-27T22:30:54.333 に答える
3

私の頭に浮かんだ特定の利点の 1 つは (あなたが例を求めたので)、Java ではプリミティブ型 ( int, boolean ...) であり、Scala では暗黙的な変換で機能を追加できるオブジェクトです。たとえば、toRomanメソッドを ints に追加する場合は、次のような暗黙のクラスを記述できます。

implicit class RomanInt(i:Int){
  def toRoman = //some  algorithm to convert i to a Roman representation
}

Int次に、次のような任意のリテラルからこのメソッドを呼び出すことができます。

val romanFive = 5.toRoman  // V

このようにして、基本的なタイプをニーズに合わせて「ポン引き」することができます

于 2013-03-27T22:01:04.050 に答える
3

利点は、言語内で異なる規則に従う異なる演算子がないことです。たとえば、Java でオブジェクトに関連する操作を実行するにはdot name、コードを呼び出す手法を使用します (静的オブジェクトは引き続きこのdot name手法を使用しますが、場合によってはthis objectまたはstatic objectが推測されます)。組み込みアイテム (オブジェクトではない) は別のメソッドを使用します。組み込みのオペレータ操作の。

Number one = Integer.valueOf(1);
Number two = Integer.valueOf(2);
Number three = one.plus(two); // if only such methods existed.

int one = 1;
int two = 2;
int three = one + two;

主な違いは、dot name手法が多態性、演算子のオーバーロード、メソッドの隠蔽、および Java オブジェクトで実行できるすべての優れた機能の影響を受けることです。この+手法は事前定義されており、完全に柔軟ではありません。

Scala は、+基本的にメソッドを演算子として扱いdot name、そのような演算子からオブジェクト メソッドへの強力な 1 対 1 のマッピングを定義することで、メソッドの柔軟性のなさを回避しています。したがって、Scala ではすべてがオブジェクトであるということは、すべてがオブジェクトであることを意味するため、操作は

 5 + 7

その結果、2 つのオブジェクト (5 オブジェクトと 7 オブジェクト) が作成され、5 オブジェクトの plus メソッドがパラメーター 7 で呼び出され (私のスカラ メモリが正しく機能する場合)、"12" オブジェクトが の値として返されます。5 + 7手術。

このすべてがオブジェクトであることは、関数型プログラミング環境で多くの利点があります。厳密な型チェック (コードのブロックは、Longまたはそのサブクラスのみを返しますString)。

要約すると、ある種のソリューションの実装が非常に簡単になり、多くの場合、「プリミティブへの移動、操作、プリミティブからの移動」マーシャリング コードを処理する必要がないため、非効率性が緩和されます。

于 2013-03-27T21:44:24.500 に答える
2

他の人が指摘した点に加えて、Scala ですべての値を一様に扱うことは、一部は幻想であることを常に強調します。ほとんどの場合、それは非常に歓迎すべき錯覚です。また、Scala は、実際の JVM プリミティブを可能な限り使用し、自動変換 (通常はボックス化およびボックス化解除と呼ばれます) を必要なだけ実行するという点で非常にスマートです。

ただし、自動ボックス化およびボックス化解除のアプリケーションの動的パターンが非常に高い場合、それに関連して望ましくないコスト (メモリと CPU の両方) が発生する可能性があります。これは、特定の型パラメーターが (プログラマー指定の) プリミティブ型である場合にジェネリック クラスの特別なバージョンを作成する、特殊を使用して部分的に軽減できます。これにより、ボックス化とボックス化解除が回避.classされますが、実行中のアプリケーションでより多くのファイルが必要になります。

于 2013-03-27T22:06:27.270 に答える