Case-classes及其默认构造函数

Dmi*_*lov 1 scala typechecking akka

假设,我定义了案例类:

case class A(id: Int)
Run Code Online (Sandbox Code Playgroud)

然后我突然输入了这段代码:

val a = A
Run Code Online (Sandbox Code Playgroud)

问题是 - 为什么编译器允许这样的着作?在Java中,使用任何参数定义构造函数会使默认构造函数不可用.

编辑:好的,正如Ende Neu指出的那样,a现在包含了A.type.如何突然输入a = A可能会破坏我的代码:

a match {
   case A(id) => do something
   case _ => I didn't expect fall into here
}
Run Code Online (Sandbox Code Playgroud)

我试图避免陷入我的Akka消息处理代码中的第二种情况.可能吗?

更新:花了一些时间与Akka + Scala一起工作后,我想出了这个问题第二部分的答案.Actor的receive方法有签名PartialFunction[Any, Unit],这意味着输入参数没有类型检查.所以任何类型都被接受,包括A.type.在此上下文中对用户的最佳建议:在向演员发送消息时要小心.

End*_*Neu 5

您分配A.typea:

scala> case class A(id: Int)
defined class A

scala> val a = A
a: A.type = A

scala> a()
<console>:11: error: not enough arguments for method apply: (id: Int)A in object A.
Unspecified value parameter id.
            a()
             ^

scala> a(1)
res1: A = A(1)
Run Code Online (Sandbox Code Playgroud)

在赋值a类型A.type之后,您可以使用a构造案例类的新实例A,但仍需要指定id参数.

关于你的编辑:

a match {
  case A(id) => do something
  case _ => I didn't expect fall into here
}
Run Code Online (Sandbox Code Playgroud)

我认为这在这种情况下正确抛出异常,因为你想要一个类型的变量,A而你最终得到一个类型的变量A.type,这很可能是一个错误,如果你真的想区分AA.type你的匹配这样的事情应该工作:

scala>  val a = A
a: A.type = A

scala>  a match {
     |    case a: A.type => "A.type"
     |    case someA: A => "case class"
     |    case _ => "default"
     |  }
<console>:13: warning: fruitless type test: a value of type A.type cannot also be a A
                    case someA: A => "case class"
                            ^
<console>:13: warning: unreachable code
                    case someA: A => "case class"
                                 ^
res8: String = A.type

scala> val someA = A(1)
someA: A = A(1)

scala>  someA match {
     |    case a: A.type => "A.type"
     |    case someA: A => "case class"
     |    case _ => "default"
     |  }
<console>:12: warning: fruitless type test: a value of type A cannot also be a A.type
                    case a: A.type => "A.type"
                         ^
res9: String = case class
Run Code Online (Sandbox Code Playgroud)

但正如我所说,这感觉很奇怪,可能有一个更好的解决方案,我不知道这类问题.