Geo*_*org 5 scala pattern-matching case-class
在下面的例子中,在第二个中case
我会期望与第一个相同的编译错误case
,但它编译.为什么?
object CaseMatching extends App {
case class Id(value: Long)
object Id { val zero = Id(0) }
case class Name(value: String)
case class IdName(id: Id, name: Name)
IdName(Id(0), Name("A")) match {
case IdName(_, Id(0) ) => // does not compile (as expected)
case IdName(_, Id.zero) => // does compile (but should not ?)
case IdName(Id.zero, _) => println("OK") // this is OK and will match
case _ =>
}
}
Run Code Online (Sandbox Code Playgroud)
为什么相关?- 我花了大部分时间来找出为什么从未遇到过以下情况:case TreeEntry(_, Some(child), _, _, NodeType.DIR, _, _)
那就是,因为NodeType在第4个字段而不在第5个字段中.如果编译器告诉我,我会很感激!
最简单的答案:使用Name
final足以说服编译器这zero
不是一个。请参阅此问题和环境。
它会在类型测试上发出警告,这是一个 isInstanceOf:
<console>:15: warning: fruitless type test: a value of type CaseMatching.Name cannot also be a CaseMatching.Id
case IdName(_, _: Id) =>
^
Run Code Online (Sandbox Code Playgroud)
但在测试平等时则不然,因为平等是普遍存在的。
这里还有一个不错的,case IdName(_, Id) =>
<console>:15: error: pattern type is incompatible with expected type;
found : CaseMatching.Id.type
required: CaseMatching.Name
Note: if you intended to match against the class, try `case _: Id`
case IdName(_, Id) =>
^
Run Code Online (Sandbox Code Playgroud)
你想要的是:
scala> IdName(Id(0), Name("A")) match { case IdName(_, id: Id.zero.type) => }
<console>:21: warning: fruitless type test: a value of type Name cannot also be a Id (the underlying of Id.zero.type)
IdName(Id(0), Name("A")) match { case IdName(_, id: Id.zero.type) => }
^
Run Code Online (Sandbox Code Playgroud)
单例类型仅包含该值,因此它用于eq
测试;作为类型测试,它还会发出警告。(它使用的eq
是而不是equals
本周的。)
不确定这对你来说有多远,但是:
scala> :pa
// Entering paste mode (ctrl-D to finish)
sealed trait Id { def value: Long }
case class Nonzero(value: Long) extends Id
case object Zero extends Id { val value = 0L }
case class Name(value: String)
case class IdName(id: Id, name: Name)
// Exiting paste mode, now interpreting.
scala> IdName(Zero, Name("A")) match { case IdName(_, Zero) => 1 }
<console>:14: error: pattern type is incompatible with expected type;
found : Zero.type
required: Name
IdName(Zero, Name("A")) match { case IdName(_, Zero) => 1 }
^
Run Code Online (Sandbox Code Playgroud)