Вызовите метод значения Scala Option, если он есть - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь найти лучший способ реорганизовать следующий код, чтобы исключить использование Option.get ().Я знаю, что использование метода get считается плохой практикой.

if (myConnection.isDefined) {
  myConnection.get.close
}

, где myConnection имеет тип Option [Connection]

getOrElse не похоже, что он будет работать, потому что нетобъект "else" для вызова метода.Если myConnection None, то я не хочу ничего делать.

Я полагаю, я мог бы использовать forEach, например:

myConnection.foreach{ c => c.close }

Это сработало бы, но мне это показалось странным.В моем случае myConnection никогда не будет содержать более одного соединения, и кто-то еще позже, посмотрев на мой код, может поверить, что он может содержать несколько соединений.

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

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

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

Вот как выглядит Option.foreach:

@inline final def foreach[U](f: A => U) {
  if (!isEmpty) f(this.get)
}

Но если вы хотите выполнить некоторые вычисления и вернуть значение,.map или match может быть лучше.

import scala.util.Try

val connectionMaybe = Try {
  DriverManager.getConnection(
    s"jdbc:h2:~/test;MODE=Oracle",
    "sa",
    ""
  )
}.toOption


def getSomething(connectionMaybe: Option[Connection]): Option[Int] = {
  connectionMaybe match {
    case Some(connection) =>
      val statement = connection.createStatement()
      val rs = statement.executeQuery(s"select * from something")
      Option(rs.getInt("some_column"))
      //cleanup if needed
    case _ =>
      println("no connection found")
      None
  }
}
0 голосов
/ 21 ноября 2018

Шаблонная версия, если вам не нравятся чисто функциональные foreach / map звонки:

myConnection match {
  case Some(conn) => 
    conn // TODO add logic here, `con` is unwrapped here
  case None => 
    // TODO add error-back logic here
}
0 голосов
/ 21 ноября 2018

Как правило, вы должны отобразить опцию для работы с его значением.

myConnection.map(c => c.close())

или

myConnection.map(close(_))

, которая ничего не изменит, если c равно None, и вернет значениеNone.В противном случае, вы получите Some(True), если, например, close() вернет True при успешном завершении.Если close() не имеет возвращаемого значения, то отображение вернет Some(()), который имеет тип Option[Unit].

...