簡體   English   中英

映射Scala期貨

[英]Mapping Scala Futures

假設我有一個Future[Seq[Int]] ,我想將其轉換為Future[Seq[String]] 目前我這樣做:

 val futureSeqString = futureSeqInt.map( x => x.map(_.toString()))

這可行,但嵌套的地圖似乎有點尷尬。 Future[Option[Int]]的等效轉換稍好一些,但仍然不覺得我是這樣做的最佳方式:

val futureOptionString = futureOptionInt.map {       
  case Some(x) => x.toString(); 
  case _ => None;
}

有沒有更好的方法來解決這個問題?

雙重嵌套需要雙重映射,所以是的,在vanilla scala中,你所做的是正確的。

但是,如果我們考慮一下這個理論, ListFuture都有一個map操作,這使得它們成為Functors (這是一個過於簡單化,但請耐心Functors

兩個Functors一般可以組成,這樣你就可以組成FunctorFutureFunctorList實行“聯合” map操作。

這是一個使用cats的例子:

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import cats._
import cats.std.future._
import cats.std.list._

// create a `Functor[Future[List]`
val futureListF = Functor[Future].compose(Functor[List])

val data = Future.successful(List(1, 2, 3))

// only one map!    
futureListF.map(data)(_.toString) // Future(List("1", "2", "3"))

當然,您可以使用Option執行相同的操作。

val futureOptionF = Functor[Future].compose(Functor[Option])
val data = Future.successful(Option(42))
futureOptionF.map(data)(_.toString) // Future(Some("42"))

獎勵,無論嵌套的深度如何,您都可以使用相同的技術:

type ListOption[+A] = List[Option[A]]
implicit val listOptionF = Functor[List].compose(Functor[Option])
val futureListOptionF = Functor[Future].compose(Functor[ListOption])

// the above three lines could just be
// val futureListOptionF = Functor[Future].compose(Functor[List].compose(Functor[Option]))
// if only SI-2712 were fixed

val data = Future.successful(List(Some(42), None, Some(2)))

// triple nesting? Still a single map!
futureListOptionF.map(data)(_.toString) // Future(List(Some("42"), None, Some("2")))

就個人而言,我沒有看到嵌套地圖有任何問題。 你只需要更好地格式化和縮進它:

  future.map { seq =>
    seq.map(_.toString)
  }

有些人在這種情況下也發現有用for理解(更重要的是,當你需要一起處理幾個未來時)。

 for {
   seq <- future
 } yield seq.map(_.toString)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM