首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在sing @ in match case中使用模式绑定的类型推断不像预期的那样工作

在sing @ in match case中使用模式绑定的类型推断不像预期的那样工作
EN

Stack Overflow用户
提问于 2021-06-06 19:31:32
回答 1查看 130关注 0票数 2

假设Lofty是一个封闭的特性,而Earthy是它的案例类之一。在这样的匹配中:

代码语言:javascript
复制
loftyItem match {
...
 case e @ Earthy(x,y,z) => { foo(e) }
...
}

如果foo期望一个Earthy作为参数,编译器就会崩溃,因为e只被推断为Lofty类型。我可以解决这个问题,但它不符合我的模式,事情应该是怎样的。(我正在使用Scala2.13.5。)有人能解释为什么编译器的行为是有意义的,并让我再次对Scala感到高兴吗?

在答复意见时,让我更确切地说:

代码语言:javascript
复制
object QTest {
  trait Ethereal

  case class Lofty[A <: Ethereal](val slotMaybe: Option[A]) {
  }

  class Earthy(val field: Int) extends Ethereal

  object Earthy {
    def apply(fx: Int): Earthy = {
      new Earthy(fx)
    }

    def unapply(x: Ethereal): Option[Int] = x match {
      case y: Earthy => Some(y.field)
      case _ => None
    }
  }

  def testReally(just: Lofty[Ethereal]):
      Lofty[Earthy] = {
    just.slotMaybe match {
      case Some(c) => c match {
        case cnfC @ Earthy(i) => {
          just.copy(slotMaybe = Some(cnfC))
        }
        case _ => throw new RuntimeException("oops")
      }
      case _ => throw new RuntimeException("oops")
    }
  }
}

编译这会产生错误:

代码语言:javascript
复制
QTest.scala:25: error: type mismatch;
 found   : QTest.Ethereal
 required: QTest.Earthy
          just.copy(slotMaybe = Some(cnfC))

我显然得出了一个结论,但完整的例子似乎也有同样的问题。为什么编译器要推断Ethereal类型为cnfC而不是Earthy?即使编译器在大多数@的使用中都得到了正确的类型,为什么它会在这里出错呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-06 19:49:08

SLS 8.1.3型粘结剂

如果模式只匹配类型p的值,那么模式T就意味着该类型的T

模式Earthy(i)

代码语言:javascript
复制
case cnfC @ Earthy(i) =>

表示萃取器模式,意味着它将根据您对unapply的定义进行匹配。

代码语言:javascript
复制
object Earthy {
  def unapply(x: Ethereal): Option[Int] = ???
}

因为声明的x类型是更宽的Ethereal,而不是更窄的Earthy,所以它将不匹配。

..。只有T类型的值

但是它也可以与T = Earthy的其他子类型相匹配。因此,编译器只能确定它将是一些Ethereal

如果希望将其编译为提取器模式,则将unapply声明为

代码语言:javascript
复制
object Earthy {
  def unapply(x: Earthy): Option[Int] = ???
}

或者更好的是用例类来代替它自动获得正确的unapply

代码语言:javascript
复制
case class Earthy(field: Int) extends Ethereal
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67862964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档