2014-11-23 77 views
3

我使用ReactiveMongo用MongoDB的一个游戏框架应用程序,我有以下代码:创作期货与理解力

def categories(id: String): Future[Vector[Category]] = {...} 
.... 
val categoriesFuture = categories(id) 
for { 
    categories: Vector[Category] <- categoriesFuture 
    categoryIdsWithoutPerson: Vector[BSONObjectID] <- findCategoryIdsWithoutPerson(categories.map(_.id), personId) //Returns Future[Vector[BSONObjectID]] 
    categoriesWithoutPerson: Vector[Category] <- categories.filter(category => categoryIdsWithoutPerson.contains(category.id)) //Play cites the error here 
} yield categoryIdsWithoutPerson 

为了解释这个代码,我取包裹的Categories一个VectorFuture,因为这是ReactiveMongo如何滚动。在for的理解中,我使用Vector来从数据库中获取一个id列表。最后,我使用一个filter调用来仅保留那些可以在该id列表中找到id的类别。

这一切似乎相当简单。问题是,游戏给了我下面的编译错误的for理解的最后一行:

pattern type is incompatible with expected type; 
found : Vector[com.myapp.Category] 
required: com.myapp.Category 

我不知道为什么所需的类型是Category一个实例。

我可以使用一些洞察力来了解我在做什么错误和/或是否有更简单或更习惯的方式来完成此操作。

+0

你可以张贴的 '类别' 方法的签名?以及在哪一行检测到错误? – ale64bit 2014-11-23 21:47:31

+0

按要求澄清。谢谢。 – Vidya 2014-11-23 21:59:15

+0

只是好奇,为什么你产生categoryIdsWithoutPerson为结果?什么是理解的最后一行? – ale64bit 2014-11-23 22:02:28

回答

5

它看起来像你想编写FuturesVector。对于scala的理解必须都是相同的更高类型,在你的情况下是Future。当你展开理解的'糖'时,它只需要调用flatMap就可以了。

for { 
    categories <- categoriesFuture 
    // I'm not sure what the return type is here, but I'm guessing it's a future as well 
    categoryIdsWithoutPerson <- findCategoryIdsWithoutPerson(categories.map(_.id), personId) 
    // Here we use = to get around need to flatMap 
    categoriesWithoutPerson = categories.filter(category => categoryIdsWithoutPerson.contains(category.id)) 
} yield categoryIdsWithoutPerson 

你的代码去加糖:

categoriesFuture.flatMap(categories => 
    findCategoryIdsWithoutPerson(categories.map(_.id), personId). 
    flatMap(categoryIdsWithoutPerson => 
     categories.filter(category => categoryIdsWithoutPerson.contains(category.id)). 
      map(_ => categoryIdsWithoutPerson))