Scala - Попробуйте преобразовать метод сопоставления с сопоставлением с картой - PullRequest
0 голосов
/ 04 марта 2019

Я прочитал о transform методе Попробуйте и сравните этот метод с другими методами, чтобы выяснить, какой из них будет более понятным для кодирования.Я покажу вам код ниже

val value: Try[Int] = Try("1".toInt)
.transform(f => Success(f), e => Success(0))


val value2: Try[Int] = Try("1".toInt) match {
    case Success(f) => Success(f)
    case Failure(e) => Success(0)
}


val value3: Try[Int] = Try("1".toInt)
    .map(f => f)
    .recover {
      case e: Exception => 0
    }

Я хотел бы знать, какой из них будет лучше в этих случаях и почему это так?

Спасибо

1 Ответ

0 голосов
/ 04 марта 2019

Если вы хотите восстановиться после любого (не фатального) исключения, более целесообразно, чтобы результат был Int, чем Try[Int], поскольку вы знаете, что у вас есть значение успеха, поэтому самое идиоматичное решение будет выглядетькак это:

scala> import scala.util.Try
import scala.util.Try

scala> val value4: Int = Try("1".toInt).getOrElse(0)
value4: Int = 1

Если ваша реальная логика более сложна или вы просто предпочитаете быть по-настоящему явным, вы можете сопоставить шаблон:

scala> import scala.util.{ Failure, Success, Try }
import scala.util.{Failure, Success, Try}

scala> val value5: Int = Try("1".toInt) match {
     |   case Success(i) => i
     |   case Failure(_) => 0
     | }
value5: Int = 1

Если по какой-то причине вы действительно хотитев конечном итоге Try[Int], даже если вы знаете, что это всегда будет Success, я бы предложил использовать recover и NonFatal:

scala> import scala.util.Try, scala.util.control.NonFatal
import scala.util.Try
import scala.util.control.NonFatal

scala> val value5: Try[Int] = Try("1".toInt).recover {
     |   case NonFatal(_) => 0
     | }
value5: scala.util.Try[Int] = Success(1)

Обратите внимание, что это исключает ненужные .map(f => f) из вашего value3, а также заменяет универсальный case e: Exception экстрактором Scala NonFatal, который не будет соответствовать фатальным исключениям, таким как OutOfMemoryError (вы, как правило, не можете восстановиться после этих исключений, поэтому вы нея не хочу их здесь ловить).

Однако даже в этом случае было бы неразумно использовать transform, поскольку вы можете выразить операцию с помощью менее мощного комбинатора (recover)и вы всегда должны отдавать предпочтение простейшемуЭто то, что вам нужно.

На самом деле нет никакой причины возвращать сюда Try[Int], поэтому я просто выбрал бы getOrElse.

...