Scala 2.13 (im)mutable .map with 'Nothing' 参考
Scala 2.13 (im)mutable .map with 'Nothing" reference
我正在将基于 scala 2.12 的软件 scala 升级到 scala 2.13。
一些代码块被破坏并修复它们我在已经存在的代码中发现了一个奇怪的行为。
@编辑
下面我们对这个问题的一个用例进行解释。
一般问题是自 Scala 2.13 以来在可变或不可变映射中使用 .map 方法。在问题的最后我们有一个简单的重现方法,进一步我们有答案。
观察:
变量这个词用在业务领域,与
scala(或java)变量。
list 是一个包含 idProject 的 Array[Long]。
p.getVariables的return是一个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)
问题出在第6行,因为升级后它识别了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' ?
好吧,经过几个小时的搜索和努力,我发现这是 scala 2.13 的主要变化之一。
要使用在 map 对象中执行的 .map 方法的预期行为,我们需要明确说明它应该使用 Iterable 的实现(这是 scala 2.12 或更低版本中的默认实现)。
我们这样做是在 .map 调用之前添加一个 .iterator。
因此,根据我的 "easy to reproduce" 步骤是这样的:
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
我将对我的问题做一些修改,以便于那些可能有类似问题的人更容易找到。
我正在将基于 scala 2.12 的软件 scala 升级到 scala 2.13。 一些代码块被破坏并修复它们我在已经存在的代码中发现了一个奇怪的行为。
@编辑
下面我们对这个问题的一个用例进行解释。
一般问题是自 Scala 2.13 以来在可变或不可变映射中使用 .map 方法。在问题的最后我们有一个简单的重现方法,进一步我们有答案。
观察:
变量这个词用在业务领域,与 scala(或java)变量。
list 是一个包含 idProject 的 Array[Long]。
p.getVariables的return是一个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)
问题出在第6行,因为升级后它识别了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' ?
好吧,经过几个小时的搜索和努力,我发现这是 scala 2.13 的主要变化之一。
要使用在 map 对象中执行的 .map 方法的预期行为,我们需要明确说明它应该使用 Iterable 的实现(这是 scala 2.12 或更低版本中的默认实现)。 我们这样做是在 .map 调用之前添加一个 .iterator。
因此,根据我的 "easy to reproduce" 步骤是这样的:
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
我将对我的问题做一些修改,以便于那些可能有类似问题的人更容易找到。