Изменяемый.map Scala 2.13 (im) со ссылкой "Ничего"
Я обновляю программное обеспечение Scala на основе Scala 2.12 до Scala 2.13. Некоторые блоки кода были сломаны и исправляя их, я обнаружил странное поведение в уже существующем коде.
@Редактировать
Ниже у нас есть объяснение варианта использования этой проблемы.
В целом проблема заключается в использовании метода.map в изменяемых или неизменяемых картах начиная с Scala 2.13. В конце вопроса у нас есть простой способ воспроизвести, и далее у нас есть ответ.
найд.:
Термин "переменные" используется в бизнес-поле, оно не связано с переменными scala (или java).
list - это массив [Long], содержащий idProject.
Возвращением p.getVariables является Map[String, VariableSet].
Итак, после второго.map (строка 4) у нас есть массив [(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-й строке, потому что после обновления он распознает набор (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"?
1 ответ
Что ж, после долгих поисков и борьбы я понял, что это одно из главных изменений в scala 2.13.
Чтобы использовать ожидаемое поведение от метода.map, выполняемого в объектах карты, нам нужно явно сказать, что он должен использовать реализацию из Iterable (которая по умолчанию включена в Scala 2.12 или ниже). Мы делаем это, добавляя.iterator перед вызовом.map.
Так что для этого, в соответствии с моим "легко воспроизвести" шаг будет выглядеть так:
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
Я внесу несколько изменений в свой вопрос, чтобы их было легче найти для тех, у кого может быть похожая проблема.