加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为什么用模式匹配收集不能缩小特定类?

发布时间:2020-12-16 18:42:11 所属栏目:安全 来源:网络整理
导读:让我们考虑以下特征: sealed trait ABcase class A(a: Int) extends ABcase class B(b: Int) extends AB 我试图收集将集合限制为特定的子类. 如果我尝试收集,匹配单个组件并重新组合元组: scala Seq.empty[(Int,AB)].collect { case (id,a @ A(_)) = (id,a
让我们考虑以下特征:

sealed trait AB
case class A(a: Int) extends AB
case class B(b: Int) extends AB

我试图收集将集合限制为特定的子类.

如果我尝试收集,匹配单个组件并重新组合元组:

scala> Seq.empty[(Int,AB)].collect { case (id,a @ A(_))  => (id,a) } : Seq[(Int,A)]
res6: Seq[(Int,ab.A)] = List()

编译器很高兴,但如果尝试返回完整匹配:

scala> Seq.empty[(Int,AB)].collect { case x @ (_,A(_))  => x } : Seq[(Int,A)]

事情变得丑陋:

<console>:27: error: type mismatch;
 found   : Seq[(Int,ab.AB)]
 required: Seq[(Int,ab.A)]
       Seq.empty[(Int,A)]

为什么Scala编译器无法处理第二种情况?

解决方法

这似乎是因为模式匹配以自上而下的方式进入子模式,而不将任何附加信息从子模式传递到根模式.

什么时候

x @ (_,A(_))

匹配,所有x知道模式是它具有预期的类型(Int,AB),这成为x的推断类型.

但是当您将模式变量i和a附加到子模式时,可以提取更具体的信息并将其保存在i和a的推断类型中.在这个具有@A(_)的特殊情况下,the following paragraph in the spec似乎相关:

A pattern binder x@p consists of a pattern variable x and a pattern p. The type of the variable x is the static type T of the pattern p.

在A(_)的情况下,只需通过查看模式的顶级元素即可将静态类型推断为A,而不会递归到子模式中.因此,a的类型被推断为A,id的类型被推断为Int,因此(id,a)被推断为具有类型(Int,A).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读