在Java中,我们可以使用类名创建构造函数。 但是在scala中我看到了apply和unapply的不同用法。这是否与Java中构造函数的用法相同,我们可以使用apply和unapply作为构造函数?
答案 0 :(得分:5)
apply()
可以用作工厂方法(不是构造函数),而且通常是,但不限制或要求这样做。使apply()
特殊的原因只是可以“默默地”调用它。
class MyClass(arg: String) {
def apply(n: Int):String = arg*n
}
val mc = new MyClass("blah")
mc.apply(2) // res0: String = blahblah
mc(3) // res1: String = blahblahblah
您经常会在配对对象中看到apply()
用作工厂方法。
object MyClass {
def apply(s: String): MyClass = new MyClass(s)
}
val mc = MyClass("bliss") // call the object's apply() method
但是,再一次,这只是一个方便的约定,而非要求。
unapply()
(和unapplySeq()
)的不同之处在于,只要您尝试对类实例进行模式匹配,就会“静默”调用它。
class MyClass(val arg: String) {}
object MyClass {
def unapply(x: MyClass): Option[String] = Some(x.arg)
}
val mc = new MyClass("bland")
mc match {
case MyClass(s) => println(s"got $s") // output: "got bland"
case _ => println("not")
}
答案 1 :(得分:1)
不,不是。 Apply
可以调用构造函数,但它不是平等的东西,它来自函数式编程范例。来自维基百科:函数应用程序是将函数应用于其域中的参数以便从其范围获取相应值的行为。所以,apply
它只是将函数应用于参数,并且在Scala monads类中是,在里面应用它们通常调用构造函数。但在其他功能中,申请可以做不同的事情。
Unapply
它是模式匹配的构造,但在语义上它反过来apply
的操作。它说:给我一个通过将函数应用于参数X而创建的对象,我将返回这个参数X.
答案 2 :(得分:1)
在java中,我们可以使用类名创建一个构造函数。 但是在scala中我看到了apply和unapply的不同用法,这和java中的构造函数一样,我们可以使用apply和unapply作为构造函数
没有
在Scala中,使用new
运算符调用构造函数(就像在Java中一样)并命名为this
(主构造函数根本没有名称,它只是正文该课程。)
apply
和unapply
不是构造函数,它们是方法。方法与Scala中的构造函数不同(就像它们在Java中一样)。关于apply
的唯一特别之处是foo()
被解释为foo.apply()
如果在范围内没有名为foo
的方法。换句话说,apply
允许您创建自己的类似函数的对象。
unapply
。它允许一个对象决定它将自己暴露给模式匹配的部分以及如何。换句话说:面对模式匹配,需要保留面向对象的数据抽象。
由于unapply
的目的是从对象中提取值,因此在某种意义上它与构造函数的确切相反,其目的是收集值和将隐藏在对象中。
答案 3 :(得分:0)
显然,区别主要在于样式。我喜欢应用apply的用法,因为从伴侣对象的角度来看,apply更具功能性。但是由于Scala没有在类中定义析构函数方法(就像您在C ++中那样),因此使用apply变得更加自然,因为您可能需要定义unapply方法,并且将有一个清晰的设计在同一级别上显式地定义这两个方法。 / p>