1

I'm upgrading a software scala based from scala 2.12 to scala 2.13. Some blocks of code was broken and fixing them I found a wierd behavior in an already existing code.

@Edit

Below we have an explanation of a use case of this problem.

The problem in general is the usage of the method .map in mutable or immutable maps since Scala 2.13. At the end of the question we have an easy way to reproduce, and further we have the answer.

Obs.:

  • The term variables used there is a business field, its not related to scala (or java) variables.

    list is an Array[Long] containing idProject.

    The return of p.getVariables is a Map[String, VariableSet].

    So after the second .map (line 4), we have an Array[(Project, Map[String, VariableSet])]

The code is:

// 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)

The problems comes at the 6th line, because after the upgrade it recognizes the set (pair._2.map(set => ) as type "Nothing" .

I tried line by line and it seems to work.

Like this:

val abs = list.map(projectById).map(p => p -> p.getVariables)
    val ab = abs.map(pair => pair._2)
    ab.map(pair => pair)

The problem here is that in the 6th line of previous example I need the reference to the project associated to that flow.

Of course, there would be room to rewrite this in another way (continuing the work on the second example), but I have many many other cases like this and would like to know if its really supposed not to work anymore of if I miss something during the upgrade.

Thanks in advance!

@Edit

Easy way to reproduce:

import scala.collection.mutable.{Map => MMap}

val mmap: MMap[String, Long] = MMap[String, Long]()

mmap.map(set => ) // Here, it recognizes 'set' as Nothing .

Looks like scala 2.13 see an element of Mutable Map as 'Nothing' ?

4

1 回答 1

3

好吧,经过几个小时的搜索和挣扎,我发现这是 scala 2.13 的主要变化之一。

要使用在 map 对象中执行的 .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

对于可能有类似问题的人,我将对我的问题进行一些更改,以便更容易找到。

于 2019-08-12T11:51:23.063 回答