Scala for推导式编译错误排查及修复咨询
问题分析与解决方案
错误原因
Scala的for推导式本质是map/flatMap/filter的语法糖。第三个推导式中,外层容器是Option[List[Int]],第一步qn <- optList会调用Option.flatMap,而flatMap要求传入的函数必须返回Option类型的结果。但你第二步num <- qn是遍历List[Int],返回的是List[Int],和外层的Option类型不兼容,因此触发类型不匹配错误。
两种可行修改方案
方案1:得到扁平化的List[Int]
如果希望最终结果是所有元素组成的List[Int](当optList为None时返回空List),可以将外层Option转换为List,让整个推导式基于List容器:
object Test { val lst: List[Int] = List(1,2,3,4) val optList: Option[List[Int]] = Option(lst) for { num: Int <- lst } yield num for { qn: List[Int] <- optList } yield qn // 修改后的代码 for { qn: List[Int] <- optList.toList // 将Option转为List,统一容器类型 num: Int <- qn } yield num }
此时推导式等价于optList.toList.flatMap(qn => qn),最终结果为List(1,2,3,4)。
方案2:保留Option上下文,得到Option[List[Int]]
如果希望保留Option的语义(optList为None时返回None,为Some时返回Some[List[Int]]),需要将内层List的遍历放在map中,而不是用嵌套的<-:
object Test { val lst: List[Int] = List(1,2,3,4) val optList: Option[List[Int]] = Option(lst) for { num: Int <- lst } yield num for { qn: List[Int] <- optList } yield qn // 修改后的代码 for { qn: List[Int] <- optList } yield qn.map(num => num) // 用map处理内层List,保持Option容器 }
如果需要对每个元素做处理(比如元素加1),可以改成:
for { qn: List[Int] <- optList } yield qn.map(_ + 1)
此时推导式等价于optList.map(qn => qn.map(num => num)),最终结果为Some(List(1,2,3,4))(若optList为None则返回None)。
内容的提问来源于stack exchange,提问作者Heitor Barbieri
相关产品推荐
相关产品推荐

