首页 文章

使用与mixin进行模式匹配时的奇怪行为

提问于
浏览
3

我可能错过了一些明显的东西,但我无法做到这一点 .

假设我们有以下代码:

object T {
  def method: Unit = {
    trait Mixin
    case class Foo(foo: String)

    val f = new Foo("hi") with Mixin
    f match {
      case Foo(s) => println(s)
    }
  }
}

当我调用Test.method时,这会编译并打印“hi” . 模式匹配代码甚至可以在嵌套方法或嵌套函数中,并且它可以工作 . 但是,如果我将case类移到方法之外并直接附加到T2:

object T2 {

  case class Foo(foo: String)

  def method: Unit = {
    trait Mixin

    val f = new Foo("hi") with Mixin
    f match {
      case Foo(s) => println(s)
    }
  }
}

它会引发以下错误:

Error:(183, 12) constructor cannot be instantiated to expected type;
 found   : T2.Foo
 required: T2.Foo with Mixin
      case Foo(s) => println(s)
           ^

如果现在我不使用Mixin,只使val f = new Foo(“hi”),它再次正常工作 . 如果我尝试匹配其类型,它也有效:

val f = new Foo("hi") with Mixin
f match {
  case f: Foo => println("I am a Foo")
}

如果案例类(及其所有生成的方法)都在范围内,为什么T2不起作用?为什么定义它的位置很重要?在我的实际代码中,我有几个案例类,在几个模块中,模式匹配器到处都是,所以我不能只在同一个方法中移动所有内容,如果我不需要,我更愿意摆脱混合,所以我还有其他选择吗?

1 回答

  • 1

    我相信有一些事情正在发生 .

    • Scala编译器正试图找出您匹配的类型 .

    • 您将顶级类型与本地类型混合在一起,这似乎使编译器感到困惑 .

    T 中, FooMixin 都在方法范围内声明为本地 . 在其范围之外不需要本地类型(在本例中为 method ) . 因为一切都在同一范围内,所以它正在努力做到 .

    T2 中, Foo 在顶层声明,但 Mixin 仍然是本地类型 . 这似乎摒弃了编译器 . 您可以通过专门键入值 fFoo 来帮助编译器,这将允许您的代码段进行编译 .

    object T2 {
      case class Foo(foo: String)
      def method: Unit = {
        trait Mixin
        val f: Foo = new Foo("hi") with Mixin
        f match {
          case Foo(s) => println(s)
        }
      }
    }
    

    我希望我能提供更详细(并保证准确)的解释 .

相关问题