Опитвам се да използвам for за изразяваневърху списък, след това направете трансформация на всеки елемент, използвайки помощна програма, която връща бъдеще. Накратко, той не се компилира и искам да разбера защо. Аз чета този въпрос, което е подобно и беше голяма помощ, но това, което се опитвам да направя, е дори по-просто, което е още по-объркващо, защо не работи. Опитвам се да направя нещо като:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
val numberList = List(1, 2, 3)
def squareInTheFuture(number: Int): Future[Int] = Future { number * number}
val allTheSquares = for {
number <- numberList
square <- squareInTheFuture(number)
} yield { square }
И това, което получавам, е:
грешка: несъответствие на типа; намерено: scala.concurrent.Future [Int] задължително: scala.collection.GenTraversableOnce [?] квадрат <- squareInTheFuture (номер) ^
Може ли някой да ми помогне да разбера защо това не работи и каква е най-добрата алтернатива?
Отговори:
7 за отговор № 1flatMap
изисква конструкторите на типа на numberList
и squareInTheFuture(number)
са едни и същи (по модул каквито и да е имплицитни преобразувания, които библиотеката за събиране прави). Това не е случаят тук. Вместо това, това е обиколка:
val allSquaresInTheFuture: Future[List[Int]] =
Future.traverse(numberList)(squareInTheFuture)
9 за отговор № 2
Най- Future
придружаващ обект има traverse
метод, който прави точно това, което искате:
val allTheSquares: Future[List[Int]] =
Future.traverse(numberList)(squareInTheFuture)
Това ще асинхронно започне всички изчисления и ще върне бъдеще, което ще бъде завършено, след като всички тези фючърси бъдат завършени.
2 за отговор № 3
@Lee е правилен. Като допълнение, ако се опитвате да направите паралелно изчисление:
val numberList = List(1, 2, 3)
val allTheSquares = numberList.par.map(x => x * x)(breakOut)
Ако наистина искате Future
:
val allTheSquares: Future[List[Int]] = Future.traverse(numberList)(squareInTheFuture)
2 за отговор № 4
Вашето за разбиране е същото като
val allTheSquares = numberList.flatMap(number => squareInTheFuture(number))
flatMap
изисква функцията "аргумент" да се връща a GenTraversableOnce[Int]
независимо от това, че вашият връща a Future[Int]
, оттук и несъответствието.