Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Case类默认应用方法_Scala_Case Class - Fatal编程技术网

Scala Case类默认应用方法

Scala Case类默认应用方法,scala,case-class,Scala,Case Class,假设我们有以下案例类: case class CasePerson(firstName: String) 我们还为它定义了一个伴生对象: object CasePerson { def apply() = new CasePerson( "XYZ" ) } 请注意,在上面的示例中,我使用apply方法显式定义了一个伴生对象,而没有定义默认的apply方法: // This "default" apply has the same argument as the primary constr

假设我们有以下案例类:

case class CasePerson(firstName: String)
我们还为它定义了一个伴生对象:

object CasePerson {
 def apply() = new CasePerson( "XYZ" )
}
请注意,在上面的示例中,我使用
apply
方法显式定义了一个伴生对象,而没有定义默认的apply方法:

// This "default" apply has the same argument as the primary constructor of the case class
def apply(firstName : String) = new CasePerson(firstName)
Q:那么Scala从哪里得到这个“默认”应用?我在这里明确定义了伴生对象,没有默认的apply,编译器仍然知道如何执行它:

val casePerson = CasePerson("PQR")

这是如何工作的?

Scala案例类是语法糖。当您创建一个case类时,Scala编译器将为您创建一个带有
apply
unapply
方法的伴生对象,然后您可以像使用它一样使用它。是指向案例类更深入信息的链接。

您还可以为您的
firstName
类参数指定默认值。因此,您可以创建一个不传递任何参数的实例

例如:

case class CasePerson(firstName : String = "XYZ")
val person = CasePerson()

Case类隐式地伴随着一个带有
apply()
的伴随对象,该对象具有与Case类的主构造函数相同的参数

即:

case class CasePerson(firstName: String)
将由

object CasePerson{
   def apply(firstName: String) = new CasePerson(firstName)
}
现在,如果您还显式定义了一个伴随对象,那么您可以将其视为隐式定义对象的附加对象

例如,在您的示例中,您向伴随对象添加了一个新的
apply

object CasePerson{
   def apply() = new CasePerson("XYZ")
}
object CasePerson{
   def apply() = new CasePerson("XYZ") // the one manually added
   def apply(firstName: String) = new CasePerson(firstName) // this one is automatically added
}
在该语句中,您可以将其视为正在创建一个组合的伴生对象:

object CasePerson{
   def apply() = new CasePerson("XYZ")
}
object CasePerson{
   def apply() = new CasePerson("XYZ") // the one manually added
   def apply(firstName: String) = new CasePerson(firstName) // this one is automatically added
}
现在,如果您决定添加自己版本的
apply
,它与主构造函数具有相同的参数,那么这将掩盖case类的默认行为

object CasePerson{
   def apply() = new CasePerson("XYZ")
   def apply(s: String) = Seq(new CasePerson(s), new CasePerson(s)) // will replace the default factory for the case class
}
现在,如果您调用
CasePerson(“hi”)
,它将生成:

List(CasePerson("hi"), CasePerson("hi"))

很抱歉,我投了反对票,但这不是问题所在。重复这一点,第一个应用程序可以工作,但第二个会导致错误消息:对重载定义的引用不明确,两个方法都适用于类型为(firstName:String)A$A28的对象CasePerson。this.CasePerson和方法适用于类型为(s:String)的对象CasePersonSeq[A$A28.this.CasePerson]匹配参数类型(字符串)@Mark谢谢你让我知道!您使用的是哪个Scala版本?您使用的是REPL吗?如果您在REPL中,请确保使用
粘贴:
选项,以便在单个块中同时定义类及其伴生对象。是否有任何理由不在其他apply方法中仅使用
=CasePerson(…)
而不是使用
=new CasePerson(…)
?(除了覆盖默认值的明显情况)