Конвертировать Option [String] в Option [Path] - PullRequest
1 голос
/ 14 января 2020

У меня есть функциональность с полем типа Option [Path], затем тип данных этого поля изменился на Option [String]. Я хотел бы переписать эту функцию без использования сопоставления, возможно ли это сделать?

То, как она выглядела при samplePath: Option [Path]

samplePath.fold(new File(getResource("sample").getPath))(_.toFile)

Как это выглядит с samplePath: Option [String]

  def transformToPath(path: Option[String]): Option[Path] = {
    path match {
      case Some(st) => Some(Paths.get(st))
      case None => None
    }
  }

transformToPath(samplePath).fold(new File(getResource("sample").getPath))(_.toFile)

1 Ответ

2 голосов
/ 14 января 2020

Наиболее наивным решением было бы .map путь:

def transformToPath(path: Option[String]): Option[Path] =
   path.map(path => Paths.get(path))

Лучшим способом было бы обернуть внутреннее выражение с помощью Try[A]:

def transformToPath(path: Option[String]): Option[Path] =
   path.flatMap(path => Try(Paths.get(path)).toOption)

Обратите внимание, что это не будет сигнализировать об ошибке, произошедшей в Paths.get (которая может вызвать исключение). В идеале, мы должны также передать это вызывающей стороне:

def transformToPath(path: Option[String]): Either[Throwable, Option[Path]] =
  path.fold[Either[Throwable, Option[Path]]](Right(None))(
    path => Try(Paths.get(path)).map(Option(_)).toEither
  )

Теперь, в случае бросков Paths.get мы получим Left с Exception.

Возможно, даже лучше было бы устранение ввода Option[String], требующего строгого ввода String, что помогает нам избежать избыточной оболочки Option[Path] и вернуть прямой Path объект в случае, если мы успешно его построили:

def transformToPath(path: String): Either[Throwable, Path] =
  Try(Paths.get(path)).toEither

Теперь для этого потребуется внешний вызывающий .map через Option [String] `перед вызовом этого метода:

val result = Option(someStringFromJavaLand).map(transformToPath)
...