web-dev-qa-db-ja.com

Scalaの「新しい」キーワード

非常に簡単な質問があります-Scalaでオブジェクトを作成するときに、新しいキーワードをいつ適用する必要がありますか? Javaオブジェクトのみをインスタンス化しようとしたときですか?

87
Bober02

newの独自のコンストラクターを参照する場合は、classキーワードを使用します。

class Foo { }

val f = new Foo

コンパニオンオブジェクトのnewメソッドを参照している場合は、applyを省略します。

class Foo { }
object Foo {
    def apply() = new Foo
}

// Both of these are legal
val f = Foo()
val f2 = new Foo

ケースクラスを作成した場合:

case class Foo()

Scalaは密かにコンパニオンオブジェクトを作成し、これを次のようにします。

class Foo { }
object Foo {
    def apply() = new Foo
}

だからできる

f = Foo()

最後に、コンパニオンapplyメソッドはコンストラクターのプロキシである必要があるというルールはないことに注意してください。

class Foo { }
object Foo {
    def apply() = 7
}

// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7

また、Javaクラス:yes-Javaクラスはめったにapplyメソッドを持つコンパニオンオブジェクトを持たないため、newおよび実際のクラスのコンストラクター。

132
Owen

Javaオブジェクトのみをインスタンス化しようとしたときですか?

どういたしまして。 scalaでnewを省略した場合、2つの一般的なケースがあります。シングルトンオブジェクト(多くの場合、静的関数を格納するために使用され、Javaで見られるようなファクトリーの一種として):

scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy

scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8

scala> LonelyGuy.mood
res4: Java.lang.String = sad

ケースクラス (実際には、クラス+オブジェクト= コンパニオン パターンがあります。たとえば、同じ名前のクラスとオブジェクトがあります):

scala> case class Foo(bar: String) 
defined class Foo


scala> Foo("baz")
res2: Foo = Foo(baz)

したがって、単純なクラスを使用する場合、ルールはJavaの場合と同じです。

scala> class Foo(val bar: String) 
defined class Foo

scala> new Foo("baz")
res0: Foo = Foo@2ad6a0

// will be a error 
scala> Foo("baz")
<console>:8: error: not found: value Foo
       Foo("baz")

ボーナス、scalaには匿名クラスがあり、これは次のように構築できます。

scala> new { val bar = "baz" }
res2: Java.lang.Object{val bar: Java.lang.String} = $anon$1@10ee5b8

scala> res2.bar
res3: Java.lang.String = baz
15
om-nom-nom

Javaオブジェクトのみをインスタンス化しようとしたときですか?

Scala 3(8年後の2020年半ばにリリースされる必要があります))、 Dottyに基づいて :なし。

Scala 3はこのスレッドで として「new」をドロップします

Creatorアプリケーションでは、applyメソッドが実装されていない場合でも、単純な関数呼び出し構文を使用してクラスのインスタンスを作成できます。

例:

_class StringBuilder(s: String) {
   def this() = this(s)
}

StringBuilder("abc")  // same as new StringBuilder("abc")
StringBuilder()       // same as new StringBuilder()
_

クリエーターアプリケーションは、これまでケースクラスに対してのみ提供されていた機能を一般化しますが、これを実現するメカニズムはわずかに異なります。
自動生成された適用メソッドの代わりに、新しい可能な解釈を関数呼び出しf(args)に追加します。

0
VonC