假设我有以下代码:
object ForComprehension {
def generateSomeSeq(n: Int): List[Int] = (1 to n).toList
def square(n: Int): List[Int] =
for (x <- generateSomeSeq(n)) yield x * x
}
一切正常。但由于某种原因,我将第一个方法的结果修改为 Set
而不是 List
:
object ForComprehension {
def generateSomeSeq(n: Int): Set[Int] = (1 to n).toSet
def square(n: Int): List[Int] =
for (x <- generateSomeSeq(n)) yield x * x
}
scala 编译器提示第一个用于理解的生成器中存在类型不匹配。尽管这是有道理的,但我仍然希望它在这两种情况下都有效。毕竟,没有任何视觉线索可以理解它需要一个 List
而不是 Set
。我需要读取两个签名来诊断类型不匹配错误。
或者我一开始就不应该期待这样的语法局部性来进行理解,不是吗?
最佳答案
示例中的 for 理解实际上只是调用 map
的语法糖,而 map
的返回类型确实由调用它的类型决定。更准确地说,它是由可用的隐式 CanBuildFrom
决定的。因此,为了使代码编译,您可以将 for 理解转换为映射调用并显式传递通常隐式参数:
object ForComprehension {
def generateSomeSeq(n: Int): Set[Int] = (1 to n).toSet
def square(n: Int): List[Int] =
generateSomeSeq(n).map(x => x * x)(scala.collection.breakOut)
}
有关 breakOut
的工作原理,请参阅 this question .
关于scala - 第一个生成器会确定 for compression 的结果类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13052577/