在 Scala 3 中:为什么运行时模式匹配无法使用 JVM 反射在鸭子类型上可靠地工作?

问题描述 投票:0回答:1

考虑以下示例:

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 reflection pattern-matching scala-3 structural-typing
1个回答
4
投票

这不起作用不仅仅是一个“错误”;在语言中包含这样的东西需要大量的设计、规范和实现工作。

您所希望的功能在 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
的行为是相同的,所以这实际上并不是关于模式匹配本身,而是关于类型测试。

© www.soinside.com 2019 - 2024. All rights reserved.