Scala - проблема несоответствия типов с собственным типом (String) и Future - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть метод, которому в качестве аргумента требуется тип String:

type Identity = String
case class RequireSmth(param: Identity) extends Something

Теперь я вызываю этот метод в более сложном порядке:

createMe(as[List])(arg =>{ parse(RequireSmth(getAction(name, surname).map(bool => getData(surname, bool).id))) })

Parse выглядит как:

def parse(ob: Something)

Где:

def getAction(name: String, surname: String): Future[Boolean] = {
    someObject.get(name).map(_.getSomething(surname).isPossibleToTake.getOrElse(false)) //someObject is defined in constructor and does not matter here
}

def getData: (String, Boolean) => MyObject = {
    case ("Doe", true) => possible
    case _ => notPossible
}

MyObject, possible и notPossible определение:

case class MyObject(id : String, name: String, surname: String)

val possible = MyObject( id = "ok", name ="John", surname = "Doe")
val notPossible = MyObject( id = "not ok", name ="John", surname = "Doe")

Проблема в том, когда я вызов метода RequireSmth Я получил ошибку:

type mismatch;
found: scala.concurrent.Future[String]
required: com.my.smth.Identity (which expands to) String

Как я могу решить эту проблему, чтобы вернуть Identity (или String) вместо Future[String]?

Ответы [ 2 ]

3 голосов
/ 02 апреля 2020

Храните информацию внутри Future следующим образом:

getAction(name, surname).map(bool => getData(surname, bool).id).map(RequireSmth)

Просто продолжайте связывать операции вместе, сохраняя все внутри Future:

getAction(name, surname)
  .map(bool => getData(surname, bool).id)
  .map(RequireSmth) // Or x => RequireSmth(x) if necessary
  .map(parse)

В какой-то момент вы получите метод, который имеет побочный эффект и возвращает Unit, и он будет выполнен, когда все действия в Future завершены.

В маловероятном случае, когда вы на самом деле нужно получить значение из Future, используйте Await.result. Но в большинстве случаев в этом нет необходимости.

3 голосов
/ 02 апреля 2020

Вам нужно перевернуть вызовы метода:

val res: Future[???] = 
   getAction(name, surname)
     .map(bool => getData(surname, bool).id)
     .map(RequireSmth)
     .map(parse)

Обратите внимание, что Future[String] - это не String, это вычисление, которое даст значение в будущем, а это означает, что все стек вычислений также должен возвращать Future[T] (если вы явно не ожидаете, что блокируется и не рекомендуется).

...