为什么这种构造会导致 Scala 中出现类型不匹配错误?
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
<console>:6: error: type mismatch;
found : List[(Int, Int)]
required: Option[?]
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
如果我将 Some 与 List 进行切换,它可以正常编译:
for (first <- List(1,2,3); second <- Some(1)) yield (first,second)
res41: List[(Int, Int)] = List((1,1), (2,1), (3,1))
这也可以正常工作:
for (first <- Some(1); second <- Some(2)) yield (first,second)
最佳答案
For 推导式会转换为对 map
或 flatMap
方法的调用。例如这个:
for(x <- List(1) ; y <- List(1,2,3)) yield (x,y)
变成:
List(1).flatMap(x => List(1,2,3).map(y => (x,y)))
因此,第一个循环值(在本例中为 List(1)
)将接收 flatMap
方法调用。由于 List
上的 flatMap
返回另一个 List
,因此 for 理解的结果当然是一个 List
。 (这对我来说是新的:因为理解并不总是产生流,甚至不一定产生 Seq
s。)
现在,看看Option
中如何声明flatMap
:
def flatMap [B] (f: (A) ⇒ Option[B]) : Option[B]
请记住这一点。让我们看看错误的理解(带有 Some(1)
的错误)如何转换为一系列映射调用:
Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))
现在,很容易看出 flatMap
调用的参数返回 List
,而不是 Option
,如下所示必填。
为了解决这个问题,您可以执行以下操作:
for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)
编译得很好。值得注意的是,Option
并不是通常假设的 Seq
的子类型。
关于scala - 在 for 理解中将选项与列表组合会导致类型不匹配,具体取决于顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4719592/