我正在将基于scala 2.12的软件scala升级到scala 2.13。 一些代码块被破坏并修复,我发现在已经存在的代码中有一种奇怪的行为。
@编辑
下面我们对这个问题的用例进行了解释。
通常的问题是从Scala 2.13开始在可变或不可变的映射中使用.map方法。在问题的结尾,我们有一个简单的方法来重现,并且进一步得到了答案。
不好:
这里使用的术语变量是一个业务领域,其与 Scala(或Java)变量。
list是一个包含idProject的Array [Long]。
p.getVariables的返回是Map [String,VariableSet]。
因此,在第二个.map(第4行)之后,我们有了一个Array [(Project, Map [String,VariableSet])]
代码是:
// get the projects
list.map(projectById)
// and map their variable
.map(p => p -> p.getVariables)
// and transform them to DTOs
.map(pair => pair._2.map(set => toVariableDTO(set._2, pair._1.getId)).toArray)
// and return the union of all of them
.reduce((l, r) => l.union(r))
// and sort them by name
.sortBy(_.name.toLowerCase)
问题出在第六行,因为升级后,它会将 set ( pair._2.map(set => ))识别为类型“ Nothing”。
我逐行尝试,它似乎可以工作。
赞:
val abs = list.map(projectById).map(p => p -> p.getVariables)
val ab = abs.map(pair => pair._2)
ab.map(pair => pair)
这里的问题是,在上一个示例的第6行中,我需要引用与该流程关联的项目。
当然,还有空间可以用另一种方式重写它(继续第二个示例的工作),但是我还有很多其他类似的情况,并且想知道它是否真的不应该再工作了,如果我在升级过程中错过了一些东西。
谢谢!
@编辑
简单的复制方式:
import scala.collection.mutable.{Map => MMap}
val mmap: MMap[String, Long] = MMap[String, Long]()
mmap.map(set => ) // Here, it recognizes 'set' as Nothing .
像scala 2.13一样,将Mutable Map的元素视为“ Nothing”吗?
答案 0 :(得分:2)
好吧,经过数小时的搜索和苦苦挣扎,我发现这是scala 2.13的主要更改之一。
要使用在地图对象中执行的.map方法的预期行为,我们需要明确地说它应该使用Iterable的实现(这是scala 2.12或更低版本中的默认设置)。 我们这样做是在.map调用之前添加.iterator。
因此,按照我的“易于复制”步骤,将是这样:
import scala.collection.mutable.{Map => MMap}
val mmap: MMap[String, Long] = MMap[String, Long]()
mmap.iterator.map(set => set._2) // Now we may use the 'set' normally
对于那些可能遇到类似问题的人,我将对其问题进行一些更改以使其更容易找到。