web-dev-qa-db-ja.com

Scalaのシングルトンオブジェクトの説明

基本的に「オブジェクトSomeClass」と「クラスSomeClass」を提供し、コンパニオンクラスはクラス宣言であり、オブジェクトは singleton であるというコーディングを取得します。インスタンスを作成することはできません。だから...私の質問は主にこの特定のインスタンスでのシングルトンオブジェクトの目的です。

これは基本的にScalaでクラスメソッドを提供するための単なる方法ですか?お気に入り +ベースのメソッド Objective-C

Programming in Scala の本を読んでいて、第4章ではシングルトンオブジェクトについて説明しましたが、これが重要である理由についてはあまり詳しく説明していません。

私はここで自分より進んでいる可能性があり、後で詳しく説明する可能性があることを認識しています。もしそうなら、私に知らせてください。この本はこれまでのところかなり良いですが、「Javaではこれを行う」ことがたくさんありますが、私はJavaの経験がほとんどないので、私は少しポイントを逃しています私はこれがそのような状況の1つになることを望んでいません。

Scalaでのプログラミングウェブサイト そのJavaだった)のどこかで読んだことを覚えていませんこの本を読むための前提条件...

36
gks

はい、コンパニオンシングルトンはJava(およびC++、c#など)の静的メソッドと同等のものを提供します。

(実際、コンパニオンオブジェクトメソッドは、Java相互運用)のために「静的フォワーダー」を介して公開されます)

ただし、シングルトンはこれをはるかに超えています。

  • シングルトンは、他のクラス/トレイトからメソッドを継承できますが、これはスタティックでは実行できません。
  • シングルトンはパラメータとして渡すことができます(おそらく継承されたインターフェイスを介して)
  • Javaが内部クラスを持つことができるのと同じように、シングルトンは周囲のクラスまたはメソッドのスコープ内に存在できます。
  • シングルトンがコンパニオンである必要はないことにも注意してください。コンパニオンクラスを定義せずにシングルトンを定義することは完全に有効です。

これは、ScalaJava(静的メソッドはオブジェクトに属さない)よりもはるかにオブジェクト指向の言語にするのに役立ちます。皮肉なことに、機能的な資格情報の観点から主に議論されています。

56
Kevin Wright

多くの場合、ソフトウェアシステム内の一意のオブジェクトを表すためにシングルトンが必要です。太陽系について考えてみてください。以下のクラスがあるかもしれません

class Planet
object Earth extends Planet
object Sun extends Planet

オブジェクトはシングルトンを作成する簡単な方法です。もちろん、Javaの静的メソッドとして、通常はクラスレベルのメソッドを作成するために使用されます。

15
jilen

与えられた答えに加えて(そしてjilenと同じ一般的な方向に進む)、objectsはScalaのimplicitメカニズムで重要な役割を果たします。型クラスのような振る舞いを可能にする(Haskellから知られているように):

trait Monoid[T] {
  def zero:T
  def sum(t1:T, t2:T):T
}

def fold[T](ts:T*)(implicit m:Monoid[T]) = ts.foldLeft(m.zero)(m.sum(_,_))

これで、fold-関数ができました。これは、Tに適切なMonoid(ニュートラル要素を持ち、何らかの方法で一緒に「追加」できるもの)がある限り、いくつかのTを一緒に「折りたたむ」。これを使用するには、oneあるタイプのMonoidTのインスタンスのみが必要です。これは、objectの完璧なジョブです。

implicit object StringMonoid extends Monoid[String] {
  def zero = ""
  def sum(s1:String, s2:String) = s1 + s2
}

今これは動作します:

println(fold("a","bc","def"))  //--> abcdef

したがって、objectsはそれ自体で非常に役立ちます。

しかし、まだまだあります!コンパニオンオブジェクトは、コンパニオンクラスを拡張するときに、一種の「デフォルト構成」としても機能します。

trait Config {
  def databaseName:String
  def userName:String
  def password:String
}

object Config extends Config {
  def databaseName = "testDB"
  def userName = "scott"
  def password = "tiger"
}

したがって、一方では特性Configがあり、ユーザーはこれを好きなように実装できますが、他方では、デフォルト設定を使用したい場合は既製のオブジェクトConfigがあります。

4
Landei

はい、基本的には、コンパニオンオブジェクトとして使用する場合に クラスメソッド を提供する方法です。

2
Casual Jim