Посмотрите на код ниже — где в нём проблема? Пишите ваши мысли в комментариях, а ниже мы дадим решение ошибки.
object UnitError {
def printMsg(message: String): Unit = {
println(message)
}
def process(data: List[Int]): List[Unit] = {
for (element <- data) yield {
printMsg(s"Элемент: $element")
}
}
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3)
val res = process(nums)
println(s"Результат: $res") // Вывод List[Unit] даёт неожиданный результат
}
}
Дальше будет решение — если не хотите спойлеров, пролистните текст ниже.
Ошибка заключается в неверной конструкции при использовании функции process. Она возвращает пустые значения: List((), (), ()). Происходит это потому, что yield собирает результаты каждой итерации. В итоге получается список, состоящий из пустых значений Unit — по одному на каждый элемент в data.
Unit в Scala — это аналог void в Java и Си-подобных языках, означающий пустое значение. В данном примере yield собирает результаты printMsg(...), которые все являются Unit (пустыми).
Программисты, привыкшие к императивным языкам и переходящие на Scala, интуитивно ожидают, что такая конструкция будет возвращать какие-то преобразованные данные, например — как это делает map в JavaScript. То есть, начинающие скалисты могут ожидать здесь на выходе список элементов, а получат пустой вывод.
Исправление
Если требуется вернуть список преобразованных значений, тогда нужно использовать эти значения в yield.
def printMsg(message: String): String = { // Теперь возвращает String
println(message)
message // Возвращает саму строку
}
def process(data: List[Int]): List[String] = { // Теперь функция возвращает List[String]
for {
element <- data
} yield {
printMsg(s"Обрабатываем элемент: $element") // Теперь выводится результат String
}
}