gpt4 book ai didi

scala - 从 Seq 到 Set 再到 Seq 的转换

转载 作者:行者123 更新时间:2023-12-04 03:23:25 27 4
gpt4 key购买 nike

直观地,以下应该起作用:

case class I(i: Int)
val s = Seq(I(1),I(2),I(3))
s.sortBy(_.i) // works
s.toSeq.sortBy(_.i) // works
s.toSet.toSeq.sortBy(_.i) // doesn´t work

为什么它的行为不像预期的那样?

最佳答案

这是混合协变和不变集合的复杂影响。集合是不变的:Set[A] .但 Seq 是协变的:Seq[+A] .现在,假设您想要一个 toSet您的 Seq 中的方法。你可以试试 toSet: Set[A] .但这行不通,因为如果 AB 的子类,然后 Seq[A]应该被视为 Seq[B] 的子类.然而,Seq[A]坚持退货Set[A]这不是 Seq[B] 的子类.所以我们的打字坏了。

另一方面,如果我们指定 toSeq[B >: A]: Set[B]那么一切都很好:如果我们保证我们可以返回任何父类(super class),那么 Seq[A]可以退货Set[B]以及 Set[C]哪里CB 的父类(super class). Seq[B] promise 退货Set[B]或一些 Set[C]另外,所以我们很清楚:Seq[A] 上的方法可以做Seq[B]上的方法的所有事情可以做。

但是现在看看可怜的打字员面临的问题:

s.toSet[B >: I]
.toSeq/* Type B >: I*/
.sortBy[C](/* some f:B => C */)(/* implicit ordering on C */)

有一种方法可以解决这个问题——即决定 BI并输入函数和 C因此。但这将是一个非常复杂的搜索,而且编译器现在无法处理。所以它要求你帮助它输入函数的输入类型,以便它知道 B在那一点(然后可以将其传播回 toSet )。

但是,如果您愿意,您可以在多个层面上提供帮助:
s.toSet[I].toSeq.sortBy(_.i)
s.toSet.toSeq.sortBy[Int](_.i)

或者您可以通过向它证明在选择与早期类型的最佳匹配时不需要考虑后期类型来帮助它:
{ val temp = s.toSet; temp }.toSeq.sortBy(_.i)
s.toSet match { case x => x.toSeq.sortBy(_.i) }

关于scala - 从 Seq 到 Set 再到 Seq 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5433035/

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