[英]Scala: composing queries inside for comprehension giving errors
我正在嘗試正確執行此查詢,但出現錯誤。 首先,searchUser返回一個匹配的UserEntries序列,其中包含用戶的唯一ID,對於每個userId,還有第二個查詢從另一個表中獲取一些其他用戶信息+地址。
碼:
def searchUsers(pattern: String) = auth.SecuredAction.async {
implicit request =>
usersService.searchUser(pattern) flatMap { usrList =>
for {
u <- usrList
ui <- usersService.getUsersWithAddress(u.id)
} yield {
Ok(views.html.UserList(ui))
}
}
}
使用的API的簽名:
def searchUser(pattern: String): Future[Seq[UserEntry]] = ...
def getUsersWithAddress(userId: Long): Future[Seq[(UserProfile, Seq[String])]] = ...
錯誤:
[error] modules/www/app/controllers/Dashboard.scala:68: type mismatch;
[error] found : scala.concurrent.Future[play.api.mvc.Result]
[error] required: scala.collection.GenTraversableOnce[?]
[error] ui <- usersService.getUsersWithAddress(u.id)
[error] ^
[error] one error found
[error] (www/compile:compileIncremental) Compilation failed
如果我注釋掉“ u <-usrList”行並為下一行的用戶標識硬編碼,例如“ ui <-usersService.getUsersWithAddress(1L)”,則它可以工作。 知道我缺少什么嗎?
當您在中使用多個生成器進行理解時,單子必須是同一類型。 例如,您不能:
scala> for{ x <- Some("hi"); y <- List(1,2,3) } yield (x,y)
<console>:11: error: type mismatch;
found : List[(String, Int)]
required: Option[?]
for{ x <- Some("hi"); y <- List(1,2,3) } yield (x,y)
^
您可以做的是將一個或另一個轉換為正確的類型。 對於上面的示例,將為:
scala> for{ x <- Some("hi").toSeq; y <- List(1,2,3) } yield (x,y)
res2: Seq[(String, Int)] = List((hi,1), (hi,2), (hi,3))
在您的特定情況下,一個生成器是GenTraversableOnce,另一個是Future。 您可能可以使用Future.successful(theList)獲得兩個期貨。 例如,請參見此處的答案:
基於@Brian的答案,得出了一個解決方案..以下工作(無法輸入格式器代碼塊作為注釋-因此添加為答案):
usersService.searchUser(pattern) flatMap { usrList =>
val q = for {
u <- usrList
} yield (usersService.getUserWithAddress(u.id))
val r = Future.sequence(q)
r map { ps =>
Ok(views.html.UserList(ps))
}
}
為了理解,積累了期貨,然后將序列展平並映射。 希望這是完成的!
注意:我也不得不將getUserWithAddress的簽名更改為X而不是Seq [X]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.