考虑以下示例:
object MatchDuckType {
trait Sup
class Sub1() extends Sup {
def v1: String = "a"
}
def example(v: Any) = {
v match {
case _: Sup { def v1: String } => println(1)
case _ => println(2)
}
}
def main(args: Array[String]): Unit = {
example(Sub1())
example(1)
}
}
编译器给出以下错误:
MatchDuckType.scala:16:12: the type test for xxx.MatchDuckType.Sup{v1: String} cannot be checked at runtime
这个说法显然是错误的,因为
Sup { def v1: String }
可以通过Java运行时反射轻松检查(通过首先获取术语的类,然后获取其方法签名)。为什么警告仍然存在?是编译器的bug吗?
这不起作用不仅仅是一个“错误”;在语言中包含这样的东西需要大量的设计、规范和实现工作。
您所希望的功能在 Scala 2 或 Scala 3 中都不存在。
我发现了一个可以追溯到 2007 年的功能请求(!),但它从未引起太多关注:https://github.com/scala/bug/issues/329
即使该功能确实存在,该功能也将是特定于平台的并且范围有限:它只能在 JVM 上工作,不能在 JS 或 Native 上工作,并且它只适用于可以忠实地实现的细化类型的子集。以字节码表示。这就遗漏了很多 Scala 类型系统。
(至少没有
TypeTag
,但 TypeTag
仅限 Scala 2;基于 TypeTag
的匹配的功能请求是 https://github.com/scala/bug/issues/6517 。在Scala 3 上下文,考虑尝试使用匹配类型来代替?)
至于你关于脱糖的评论,模式将脱糖与
isInstanceOf
相匹配,并且isInstanceOf
的行为是相同的,所以这实际上并不是关于模式匹配本身,而是关于类型测试。