简体   繁体   English

Scala中的“new”关键字

[英]“new” keyword in Scala

I have a very simple question - when should we apply the new keyword when creating objects in Scala? 我有一个非常简单的问题 - 在Scala中创建对象时应该何时应用new关键字? Is it when we try to instantiate Java objects only? 是在我们尝试仅实例化Java对象时?

Use the new keyword when you want to refer to a class 's own constructor: 如果要引用class自己的构造函数,请使用new关键字:

class Foo { }

val f = new Foo

Omit new if you are referring to the companion object's apply method: 如果您指的是伴随对象的apply方法,请省略new

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

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

If you've made a case class: 如果你做了一个案例类:

case class Foo()

Scala secretly creates a companion object for you, turning it into this: Scala秘密为你创建了一个伴侣对象,将其转化为:

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

So you can do 所以你可以做到

f = Foo()

Lastly, keep in mind that there's no rule that says that the companion apply method has to be a proxy for the constructor: 最后,请记住,没有规则表明companion apply方法必须是构造函数的代理:

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

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

And, since you mentioned Java classes: yes -- Java classes rarely have companion objects with an apply method, so you must use new and the actual class's constructor. 而且,既然你提到了Java类:是的 - Java类很少有带有apply方法的伴随对象,所以你必须使用new和实际类的构造函数。

Is it when we try to instantiate java objects only? 是在我们尝试仅实例化java对象时?

Not at all. 一点也不。 There is two general cases when you ommit new in scala. 在scala中省略new时有两种常见情况。 With singleton objects (that are oftenly used to store static functions and as a kind of factory similar to what you may seen in java): 使用单例对象(通常用于存储静态函数,并且作为一种类似于您在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

With a case classes (actually, underneath there are class + object = companion pattern, eg having class and object with the same name): 使用案例类 (实际上,下面有class + object = 伴随模式,例如,具有相同名称的类和对象):

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


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

So when you work with a simple classes, rules are the same as with Java. 因此,当您使用简单的类时,规则与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")

Bonus, there is a anonymous classes in scala, which can be constructed like this: 奖金,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

Is it when we try to instantiate Java objects only? 是在我们尝试仅实例化Java对象时?

With Scala 3 (which should be released mid 2020, eight years later), based on Dotty : never. 使用Scala 3(应该在2020年中期,8年后发布), 基于Dotty :永远不会。

Scala 3 will drop " new ", as in this thread Scala 3将丢弃“ new ”,就像在这个帖子中一样

Creator applications allow to use simple function call syntax to create instances of a class, even if there is no apply method implemented. 即使没有实现apply方法,Creator应用程序也允许使用简单的函数调用语法来创建类的实例。

Example: 例:

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

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

Creator applications generalize a functionality provided so far only for case classes, but the mechanism how this is achieved is slightly different. Creator应用程序概括了目前为止仅为案例类提供的功能,但实现此功能的机制略有不同。
Instead of an auto-generated apply method, we add a new possible interpretation to a function call f(args) . 我们在函数调用f(args)添加了一个新的可能解释,而不是自动生成的apply方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM