在伴生对象的apply方法中使用New关键字
在伴生对象的apply方法中使用New关键字
在使用Scala中的伴生对象时,我有点困惑。当您想要提供多个构造函数时,通常会声明一个伴生对象并重载apply
方法。但是这两种做法有什么区别呢?:
case class Node(....) object Node { def apply(...) = new Node(....) // 第一种方式 def apply(...) = Node(...) // 第二种方式 }
我看到的几乎所有示例都使用第一种形式:
- When to use companion object factory versus the new keyword
- "new" keyword in Scala
- http://alvinalexander.com/scala/how-to-create-scala-object-instances-without-new-apply-case-class
但是我的代码似乎使用这两种形式都能正常工作。使用new
关键字只有在有一个普通类时才有意义吗?(而不是一个case类)
在声明一个case class时,编译器会自动生成一个伴生对象,其中包含一个apply方法,该方法使用new关键字创建case class的对象。
因此,不需要再次创建一个包含apply方法的伴生对象来使用new关键字创建case class的对象。这个工作将由编译器完成。
然而,有时我们可能需要在伴生对象的apply方法中使用new关键字创建case class的对象。这可能是因为我们需要执行一些额外的操作,或者我们想要使用自定义的构造函数来创建对象。
然而,如果我们尝试在伴生对象的apply方法中使用new关键字创建case class的对象,编译器会提示一个错误。这是因为编译器已经自动生成了一个apply方法,并且使用new关键字来创建对象。因此,我们不需要再次使用new关键字。
解决这个问题的方法是直接调用已经由编译器生成的伴生对象的apply方法,而不是尝试使用new关键字创建对象。这可以通过在伴生对象的apply方法中调用自身来实现。以下是一个示例:
case class Person(name: String, age: Int) object Person { def apply(name: String, age: Int): Person = { // Perform some additional operations if necessary // Call the apply method of the compiler-generated companion object Person.apply(name, age) } }
在这个例子中,我们在伴生对象的apply方法中执行了一些额外的操作,并通过调用自身来调用编译器生成的伴生对象的apply方法。这样,我们就可以在伴生对象的apply方法中使用new关键字创建case class的对象。
在调用val n = Node(..)
时,编译器会将这段代码展开为Node.apply
调用。现在,其中一个apply
方法内部必须调用new
来创建类型的实例。案例类为您提供了伴生对象,其中包含一个apply
方法,以允许更简洁的语法。
当您想要提供多个构造函数时,通常会声明一个伴生对象并重载
apply
方法。
对于案例类来说,这是适用的。您还可以使用this()
提供额外的辅助构造函数:
class Foo(i: Int) { def this() { this(0) } }
请注意,这不会提供apply
提供的语法糖,您需要使用new
。
那么,当我在案例类中重载apply
时,最好在apply
内部使用new
来创建对象,是吗?
不是最好的。如果您希望,可以自由使用提供的apply
。它会在内部调用new
来创建实例。选择您喜欢的任何一种,只要确保不会递归调用自己的apply
即可。
非常感谢。