2016-07-13 10 views
1

Ich bekomme einen Typenkonflikt Fehler und ich kann nicht herausfinden, warum.Für Verständnis und Futures hat einen Typ nicht übereinstimmen

found:  scala.concurrent.Future[UserSales] 
required:  Option[UserSales] 

     userSalesOpt <- getOrSetUserSales(userSalesCacheKey) 

I have tried creating another for {} clause but that didn't solve the issue. What should I be doing as I am stuck?? 

Hier sind die Methoden, die ich bin mit:

UserDAO 
    def getByUsername(name: String): Future[Option[User]] 

UserController: 
    def getOrSetUserSales(key: String): Future[Option[UserSales]] 

class UserController ... { 

    def index = Action.asyc { 
    val maybeUserSalesOpt: Future[Option[UserSales]] = for { 
     userOpt <- userDao.getByUsername(name) 
    } yield { 
     for { 
      user <- userOpt 
      userSalesCacheKey = name + "whatever" 
      userSalesOpt <- getOrSetUserSales(userSalesCacheKey) 
     } yield { 
     for { 
      userSales <- userSalesOpt 
     } yield userSales 
     } 
    } 

    for { 
     maybeUserSales <- maybeUserSalesOpt 
    } yield { 
     if(maybeUserSales.isDefined) { 
     Ok("found") 
     } else { 
     Ok("error") 
     } 

    } 

    } 

} 

Antwort

1

Der Typenkonflikt kommt aus der Definition des für Verständnis. Der resultierende Typ muss dem Anweisungstyp entsprechen.

Wenn Sie also ein Verständnis für eine Liste haben, wissen Sie, dass der resultierende Typ auch eine Liste ist.

for(i <- List(Some(1), None, Some(2)); j <- i) yield j 
res: List[Int] = List(1, 2) 

Wenn ich etwas anderes versuchen zurückzukehren, wird der Compiler beschweren:

import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

for(i <- Future.apply(Option(2)); j <- i) yield j 
<console>:**: error: type mismatch; 
found : Option[Int] 
required: scala.concurrent.Future[?] 
       for(i <- Future.apply(Option(2)); j <- i) yield j 
               ^

Sie versuchen, eine Option während der Rückgabetyp zurückkehren sollte eine Zukunft sein.


Hier ist, wie diese Art von Problem in Scala (Zusammenfassung ich alles so kompiliert) zu lösen:

// Dummy types 
type UserSales = String 
type User = String 

// Types of the main functions we have 
type GetByUsername = String => Future[Option[User]] 
type GetOrSetUserSales = String => Future[Option[UserSales]] 

// Type of the function I want 
type UserSaleGetter = (String, String) => Future[Option[UserSales]] 

// A function that solves our problem (function combinator) 
def makeConditionalUserSalesGetter(userGetter: GetByUsername, 
            salesGetter: GetOrSetUserSales): UserSaleGetter = { 
    (userName: String, prodName: String) => 
     for(optUser <- userGetter(userName); p <- salesGetter(userName+prodName)) 
      yield p 
} 

Jetzt können wir die kombinierte Funktion (mit Typ UserSaleGetter) verwenden, um einen Benutzer zu geben, und ein Produkt und erhalten Sie eine Future[Option[UserSales]].

+0

Aber mein Rückgabetyp ist Future [Option [UserSales]]? – Blankman

+0

In der 'for {user <- userOpt ...' Schleife beginnen Sie mit einer Option (userOpt) und Sie geben ein Future zurück (das von 'getOrSetUserSales()' kommt). Das beschwert sich der Compiler. – marios

Verwandte Themen