我正在尝试找出重构以下代码以消除使用Option.get()的最佳方法。我知道使用get方法被认为是不好的做法。
if (myConnection.isDefined) {
myConnection.get.close
}
其中myConnection的类型为Option [Connection]
getOrElse似乎不起作用,因为没有“ else”对象可以调用该方法。如果myConnection为None,那么我什么都不想要。
我想我可以像这样使用forEach:
myConnection.foreach{ c => c.close }
这行得通,但对我来说却很奇怪。以我为例,myConnection永远不会包含多个连接,而后来查看我的代码的其他人可能会认为它可能包含多个连接。
是否有更好的方法来做到既简洁又清晰?
答案 0 :(得分:3)
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
}
}
答案 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
}