Scala 中更好的匹配类型检查

问题描述 投票:0回答:3
scala> class A
defined class A

scala> class B
defined class B

scala> val a: A = new A
a: A = A@551510e8

scala> a match {
     | case _: B => println("unlikely")
     | case _ => println("no match")
     | }
no match

在上面的例子中,编译器不应该告诉我其中一种情况永远无法匹配吗?最近一个稍微复杂一点的例子让我感到困惑,导致了一个本应被编译器捕获的不必要的错误。

编辑:

只是为了更清楚地回答这个问题。由于某种我看不到的原因,这在 Scala 中是不可能的吗? (我可以理解类型是否使用泛型并且类型擦除会导致问题,但这看起来非常简单。)如果这并非不可能,是否有合理的理由这不在 Scala 中?如果没有的话什么时候添加? ;)

scala pattern-matching typechecking
3个回答
23
投票

目前,仅针对案例类构造函数模式进行详尽和冗余检查。原则上,编译器也可以对其他一些类型的模式执行此操作。但必须在 SLS 中具体说明要进行哪些测试。考虑到不同模式类之间的交互,这看起来可行但并不简单。因此,总而言之,这是 Scala 中可以从进一步贡献中受益的领域之一。


4
投票

如果您使用案例类,编译器会警告您(实际上编译失败):

scala> case class A()
defined class A

scala> case class B()
defined class B

scala> val a = A()
a: A = A()

scala> a match {
     | case A() => println("A")
     | case B() => println("B")
     | case _ => println("_")
     | }
<console>:13: error: constructor cannot be instantiated to expected type;
 found   : B
 required: A
       case B() => println("B")

1
投票

我检查了 Scala

2.13.3
,我们收到了
fruitless type test
的警告:

scala> a match {
     | case _:B => println("B")
     | case _ => println("no match")
     | }
       case _:B => println("B")
              ^
On line 2: warning: fruitless type test: a value of type A cannot also be a B
no match
© www.soinside.com 2019 - 2024. All rights reserved.