在伴生对象的apply方法中使用New关键字

5 浏览
0 Comments

在伴生对象的apply方法中使用New关键字

在使用Scala中的伴生对象时,我有点困惑。当您想要提供多个构造函数时,通常会声明一个伴生对象并重载apply方法。但是这两种做法有什么区别呢?:

case class Node(....)
object Node {
   def apply(...) = new Node(....) // 第一种方式
   def apply(...) = Node(...) // 第二种方式
}

我看到的几乎所有示例都使用第一种形式:

但是我的代码似乎使用这两种形式都能正常工作。使用new关键字只有在有一个普通类时才有意义吗?(而不是一个case类)

0
0 Comments

在声明一个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的对象。

0
0 Comments

在调用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即可。

非常感谢。

0