如果存在,则根据Scala Option的值调用方法

时间:2018-11-21 19:01:02

标签: scala scala-option

我正在尝试找出重构以下代码以消除使用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 :(得分:3)

在进行带有返回值foreach的副作用的计算时,

unit是有意义的。断开连接听起来很适合 foreach给我。

Option.foreach如下所示:

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

但是,如果您要进行一些计算并返回值,那么.mapmatch可能会更好。

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
  }
}

答案 1 :(得分:1)

通常,您会在Option上进行映射以对其值进行操作。

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

myConnection.map(close(_))

如果c为None则不执行任何操作,并返回None。否则,例如,如果Some(True)成功返回close()时,它将为您提供True。如果close()没有返回值,则映射将返回类型为Some(())的{​​{1}}。

答案 2 :(得分:0)

模式匹配版本,如果您不喜欢纯函数的foreach / map调用:

myConnection match {
  case Some(conn) => 
    conn // TODO add logic here, `con` is unwrapped here
  case None => 
    // TODO add error-back logic here
}