2016-07-29 135 views
1

下面的代码是真实代码的简化版本。我们“继承了”我们无法修改的域模型case object FutTestcase class FutTest。实际的领域模型是从一个数据库提供的,所以我相信Future approach是有效的,但它会导致我不明白的问题。Scala未来奇怪的编译错误

import org.scalatest.FunSpec 
import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

case object FutTest { 
    def create(sz: Int) = { FutTest(sz) } 
} 

case class FutTest(size: Int) 

class FutureTest extends FunSpec { 
    def one(v: Int): Future[FutTest] = { 
    Future { FutTest.create(v) } 
    } 
    def two(t: FutTest) = { 
    Future { FutTest.create(t.size) } 
    } 

    def compileError1: Future[FutTest] = { 
    one(10).map(f => two(f)) 
    } 

    def compileError2: Future[FutTest] = { 
    for { o <- one(10) } yield (two(o)) 
    } 
} 

错误消息:

[INFO] Using incremental compilation 
[INFO] Compiling 7 Scala sources and 5 .. target/test-classes... 
[ERROR] domain.FutureTest.scala:25: type mismatch; 
found : scala.concurrent.Future[domain.FutTest] 
required: domain.FutTest 
[ERROR]  one(10).map(f => two(f)) 
[ERROR]      ^
[ERROR] domain/FutureTest.scala:29: type mismatch; 
found : scala.concurrent.Future[domain.FutTest] 
required: domain.FutTest 
[ERROR]  for { o <- one(10) } yield (two(o)) 

我试图用普通Int代替FutTest上面的代码和所有的罚款。为什么编译器会抱怨,我们如何解决这个问题,而无需触及现有的域。

+0

我不相信这个,如果你更换'和'Int' FutTest'工作。 –

回答

5

flatMap是你想要的。

one(10).flatMap(f => two(f)) 

one(10).flatMap(two) 

使用的理解,

for { o <- one(10); t <- two(o) } yield t 
4

One()返回Futuretwo()也返回Future所以你需要flatMap而不是map。当您映射到two()时,您的结果是Future[Future[FutTest]],需要平铺。

one(10).flatMap(f => two(f)) 

应该做的伎俩。