Scala ошибка компиляции: Требуется: Будущее [S_] Найдено: Строка - PullRequest
0 голосов
/ 20 июня 2020

Следующая функция должна получить блок кода, выполнить его и вернуть future с соответствующим ответом на сообщение. Я получаю сообщение об ошибке компиляции: Требуется: Будущее [S_] Найдено: Строка, может кто-нибудь объяснить, почему?

def withTransaction(blockOfCode: => Future[User])(implicit transaction: Transaction[User]): Future[String] = Future {

  println("WithTransaction called...")

  blockOfCode.flatMap(_ => {
    transaction.commit()
    "Success"
  }).recover { // here is the error
    transaction.rollback()
    "Failed"
  }
}

1 Ответ

1 голос
/ 20 июня 2020

Future#recover ожидает частичную функцию

def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =

, которая может быть выражена с помощью фигурных скобок и синтаксиса регистра, например so

{ case e => expression }

однако, поскольку e не используется, мы могли бы также использовать отброшенный параметр синтаксис функции, согласно комментарию jwvh,

_ => expression

В вашем конкретном случае не имеет значения, какой тот, который вы выберете, но в целом частичная функция позволит вам, скажем, иметь разные типы механизмов восстановления для разных типов ошибок

{ 
  case e: SocketTimeoutException => // recovery mechanism A 
  case e: ArithmeticException   =>  // recovery mechanism B
  case ...
}

Кроме того, вам, вероятно, понадобится map вместо flatMap, потому что вы отображаются в "Success" вместо Future("Success"). Учитывайте разницу между

Future(42).map(_ => "hello")              // ok
Future(42).flatMap(_ => "hello")          // error
Future(42).flatMap(_ => Future("hello"))  // ok

Собирая вместе попробуйте

def withTransaction(
  blockOfCode: => Future[User]
)(implicit transaction: Transaction[User]): Future[String] = {
  blockOfCode
    .map { _ =>
      transaction.commit()
      "Success"
    }.recover { _ =>
      transaction.rollback()
      "Failed"
    }
}
...