gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 17:15:22 24 4
gpt4 key购买 nike

让我们考虑以下特征:

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

我正在尝试 collect将集合限制为特定的子类。

如果我尝试 collect,匹配单个组件并重新组装元组:
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, AB)].collect { case x @ (_, A(_)) => x } : Seq[(Int, A)]

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

最佳答案

似乎这是因为模式匹配以自上而下的方式进入了子模式,而没有将任何其他信息从子模式传递到根模式。

什么时候

x @ (_, A(_))

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

但是,当您将模式变量 ia附加到子模式时,可以提取更多特定信息并将其保存在推断的 ia类型中。在 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)

关于scala - 为什么用模式匹配收集不能缩小特定类别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50551318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com