使用for和yield时出现编译错误

时间:2018-04-27 14:48:27

标签: scala

以下代码段有什么问题?

val loginInfoFuture: Future[LoginInfo] = credentialsProvider.authenticate(credentials)
              for{loginInfo <- loginInfoFuture}{ 
                println("in loginInfo future")
              } yield  Future{Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json")))}

我在IDE中看到错误 - Error:(239, 17) ';' expected but 'yield' found. } yield Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json")))

我在REPL上尝试了类似的代码,但似乎工作正常。

scala> import scala.concurrent.Future
import scala.concurrent.Future

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> val f:Future[Int] = Future{1}
f: scala.concurrent.Future[Int] = Future(Success(1))

scala> for(f1 <- f) yield f1
res0: scala.concurrent.Future[Int] = Future(<not completed>)

scala>

供参考,以下是完整功能

  def signInUser = silhouette.UserAwareAction.async { implicit request => { 

val body: AnyContent = request.body
val jsonBody: Option[JsValue] = body.asJson

jsonBody match {
  case Some(json) => {

    val userSignin: Option[UserSignin] = json.asOpt[UserSignin] //check if json conforms with UserProfile structure
    userSignin match {
        case Some(signinInfo) => { //format of JSON is correct
          //Get signin info from JSON (email and password)
          val credentials: Credentials = Credentials(signinInfo.signinInfo.email, signinInfo.signinInfo.password)

          val authInfoRepository = new DelegableAuthInfoRepository(userRepo.passwordRepo)
          val passwordHasherRegistory = new PasswordHasherRegistry(userRepo.passwordHasher)
          val credentialsProvider = new CredentialsProvider(authInfoRepository, passwordHasherRegistory)


          for{loginInfo <- loginInfoFuture}{ //for returns unit. Should use yield
            println("in loginInfo future")
          } yield  Future{Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json")))}

        }
        case None => { //No signin info found
          Future {
            Ok(Json.toJson(JsonResultError("Invalid user. No Login info found")))
          }
        }
      }
    }
  case None => {//NO Body
     Future {
              Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json")))
            } 
  }
} //jsonBody match

} //异步 } // def signin

3 个答案:

答案 0 :(得分:4)

for{loginInfo <- loginInfoFuture}{ //for returns unit. Should use yield
            println("in loginInfo future")
          } yield  Future{Ok(Json.toJson(JsonResultError("Invalid Body Type. Need Json")))}

这是无效的。您的for / yield需要采用以下格式:

for {
  y <- z
  x <- y
  //etc
} yield {
  //whatever
}

在for之后但在收益之前的println抛出你。要在for / yield中获取println的结果,可以将其赋值为:

for {
  y <- z
  a = println(y)  // will print out every y
  x <- y
  //etc
} yield {
  //whatever
}
/ yield块就像那样愚蠢。至少有解决办法!

答案 1 :(得分:1)

以下部分来自scala的Future文档:

def foo(): Unit = {

    val f = Future { 5 }
    val g = Future { 3 }
    val h = for {
      x: Int <- f // returns Future(5)
      y: Int <- g // returns Future(3)
    } yield x + y

}

另一方面,你试着这样做:

def foo(): Unit = {

    val f = Future { 5 }
    val g = Future { 3 }
    val h = for {
      x: Int <- f // returns Future(5)
      y: Int <- g // returns Future(3)
    } {
      println("whatever") // <<<<<<<<<
    } yield x + y

}

我指出的额外代码块是导致编译错误的原因,你没有在scala repl示例中添加。

这是你在未来打印的方式:

def foo(): Unit = {

    val f = Future { 
      println("5")
      5 
    }
    val g = Future { 
      println("3")
      3 
    }
    val h = for {
      x: Int <- f // returns Future(5)
      y: Int <- g // returns Future(3)
    } yield x + y

}

答案 2 :(得分:1)

  
    

错误:(239,17)';'预期但发现'收益'。

  

只是意味着 for循环定义错误

所以的收益率

    for{loginInfo <- loginInfoFuture 
                //other conditions and statements
              } yield //value to be returned

没有收益

  for(loginInfo <- loginInfoFuture){ 
            //value updated
          } 

正确的循环定义