假设我定义了案例类:
case class A(id: Int)
然后我突然输入了这段代码:
val a = A
问题是 - 为什么编译器允许这样的着作?在Java中,使用任何参数定义构造函数会使默认构造函数不可用。
编辑:
好的,正如Ende Neu指出的那样,a
现在包含A.type
。
当突然键入a = A
可能会破坏我的代码时,我该如何避免使用场景:
a match {
case A(id) => do something
case _ => I didn't expect fall into here
}
我试图避免陷入我的Akka消息处理代码中的第二种情况。有可能吗?
更新:花了一些时间与Akka + Scala一起工作后,我想出了这个问题第二部分的答案。 Actor的receive
方法具有签名PartialFunction[Any, Unit]
,这意味着输入参数没有类型检查。因此接受任何类型,包括A.type
。在此上下文中为用户提供的最佳建议:在向演员发送消息时要小心。
答案 0 :(得分:5)
您要将A.type
分配给a
:
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)
在作业a
类型为A.type
之后,您可以使用a
构建案例类A
的新实例,但您仍需要指定id
参数。
关于你的编辑:
a match {
case A(id) => do something
case _ => I didn't expect fall into here
}
我认为这在这种情况下会正确抛出一个异常,因为你想要一个A
类型的变量,而你最终得到一个A.type
类型的变量,这很可能是一个错误,如果你我想真的想在你的比赛中区分A
和A.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
但正如我所说,这感觉很奇怪,可能有更好的解决方案来解决我不知道的这类问题。
答案 1 :(得分:0)
val a: A = A
会告诉你,你错了。
有很多地方你不会把它留给类型推断。
在一个本地块中,根据定义很小或我猜构造,你可以推断出类型。
如果您的a
是会员,则应始终按类型进行归档。
你永远不应该说,很久以后,在代码的一个遥远的部分,我发现推断类型是完全错误的。