Scala 中的“new”关键字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9727637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:59:20  来源:igfitidea点击:

"new" keyword in Scala

scalanew-operatorkeyword

提问by Bober02

I have a very simple question - when should we apply the new keyword when creating objects in Scala? Is it when we try to instantiate Java objects only?

我有一个非常简单的问题 - 在 Scala 中创建对象时,我们应该什么时候应用 new 关键字?是在我们仅尝试实例化 Java 对象时吗?

回答by Owen

Use the newkeyword when you want to refer to a class's own constructor:

new当您想引用 aclass自己的构造函数时,请使用关键字:

class Foo { }

val f = new Foo

Omit newif you are referring to the companion object's applymethod:

new如果您指的是伴随对象的apply方法,请省略:

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 applymethod has to be a proxy for the constructor:

最后,请记住,没有规则规定伴随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 applymethod, so you must use newand the actual class's constructor.

而且,既然您提到了 Java 类:是的——Java 类很少有带有apply方法的伴生对象,因此您必须使用new实际类的构造函数。

回答by om-nom-nom

Is it when we try to instantiate java objects only?

是在我们尝试仅实例化 java 对象时吗?

Not at all. There is two general cases when you ommit newin scala. 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):

一点也不。new在 scala 中省略时有两种一般情况。使用单例对象(通常用于存储静态函数并作为一种类似于您在 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 = companionpattern, e.g. having class and object with the same name):

使用案例类(实际上,下面有类 + 对象 =伴侣模式,例如具有相同名称的类和对象):

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@10ee5b8

scala> res2.bar
res3: java.lang.String = baz

回答by VonC

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.

使用基于 Dotty 的Scala 3(应该在 2020 年年中,也就是八年后发布):从不。

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.

Example:

Creator 应用程序允许使用简单的函数调用语法来创建类的实例,即使没有实现 apply 方法。

例子:

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.
Instead of an auto-generated apply method, we add a new possible interpretation to a function call f(args).

Creator 应用程序概括了迄今为止仅为案例类提供的功能,但实现这一点的机制略有不同。
我们为函数调用添加了一个新的可能解释,而不是自动生成的 apply 方法f(args)