当前位置: 首页 > 知识库问答 >
问题:

Scala模式匹配在2.10中的递归类型上失败

梁马鲁
2023-03-14

我有以下示例代码:

trait Recurse[T <: Recurse[T]] {
  def method = "This is a method on recurse"
}

class Foo extends Recurse[Foo] {
  override def toString = "This is a foo"
}

object Example {
  def generate: Recurse[_ /*<: Recurse[_]*/] = new Foo()
  def main(args: Array[String]) {
    val foo = generate
    foo match {
      case m: Foo => println("match: " + m)
      case _ => println("baa")
    }
    println(foo.method)
  }
}

这段代码编译并在2.9. x上正确运行(输出“匹配:这是一个foo”,后面跟着“这是一个递归方法”),但它在2.10.2上不工作。相反,我得到了编译时错误:类型参数[_1美元]不符合trait Recurse的类型参数边界[T

有趣的是,问题只出现在模式匹配器中。如果我删除匹配块,代码将编译并输出“这是递归上的一个方法”。

更有趣的是,模式匹配仍然无法编译,即使其中只有默认情况!编译器只是不接受模式匹配的递归存在类型的对象。但是,如果显式指定了foo的值(“val foo=new foo()”),或者如果类型参数不是递归的,那么即使在2.10上,代码也会编译。

这是怎么回事?为什么即使类型参数没有以任何方式参与匹配,也会中断模式匹配?有没有办法用兼容2.10的方式重写这个?

共有2个答案

史旺
2023-03-14

我相信这是Scala编译器的回归。为什么不归档呢?

郤旭东
2023-03-14

这是SI-7716,固定在2.10.3和2.11中。

 类似资料:
  • 我想消除此示例代码中的类型擦除警告: 它编译和工作正常,但有一个警告: 警告:(31,13)类型模式Seq[Int](Seq[Int]的底层)中的非变量类型参数Int未选中,因为它被擦除情况b消除:Seq[Int]= 在这种情况下,你有什么简单的解决方案来避免擦除吗? 到目前为止,我尝试了什么(根据这一点): 但是它不能编译,因为c现在是Any类型。 我相信这个问题有几种解决方法。我会接受最简单的

  • Less提供了一种机制,允许根据参数的值来改变 mixin的行为。比如,以下代码就可以让 .mixin 根据不同的 @switch 值而表现各异: .mixin (dark, @color) {   color: darken(@color, 10%); } .mixin (light, @color) {   color: lighten(@color, 10%); } 此时,在调用 .mix

  • 我有一个从提取的代码,对于多个子类来说,这个代码看起来应该完全相同,所以我尽量避免重复。但是,实际上(见下文),scala认为是一个泛型的,返回的值类型为,当然,它没有和方法。 问题是在这里避免重复的适当方法是什么?我对将转换为字符串并不那么着迷,因为这段代码可以使用刚从字符串解析为AST的json。我开始考虑为我需要的三种类型编写包装器,并将这些类型的匹配和隐式转换器转换为包装器,然后为这些包装

  • 有四种不同的类型:地点、语言、技术和行业。每个类型都有一个存储库,可以返回这些类型的集合。例如位置列表。每个类型都有一个类型为String的name属性。有一个字符串列表。它可以包含位置、语言等名称。我想编写一个函数来查找那些与字符串列表名称匹配的类型实体(位置、语言、...)。我在想这样的事情: 这是不正确的,那么如何对集合进行查询,然后如何确定name属性是否存在呢?

  • 假设我们有一个泛型类: 然后,我们希望将与和的进行模式匹配: