使用Scala选项

时间:2017-05-03 20:30:55

标签: scala

我最近更改了很多我的Scala代码,以避免使用null实例化变量,而是使用Option。例如,我之前有:

var cxn: RepositoryConnection = null
cxn = repo.getConnection()
//do something with the connection, then close it
cxn.close()

现在,我的代码看起来更像是这样。

var cxn = None : Option[RepositoryConnection]
cxn = Some(repo.getConnection())
//do something with the connection, then close it

现在我遇到的问题是当我想调用与RepositoryConnection类型相关联的方法时。我试试:

cxn.close() 

并看到此错误:

value close is not a member of Option[org.openrdf.repository.RepositoryConnection]

现在,当我使用null时,此操作运行正常,因为cxnRepositoryConnection对象,而不是Option[RepositoryConnection]。现在,我正在使用close()来调用Option方法吗?

4 个答案:

答案 0 :(得分:2)

您有几个选择。 (对不起,双关语。)最直接的可能是......

cxn.map(_.close())

但如果cxnNone,或许您需要做其他事情。然后你可以做点像......

cxn.fold(logger.reportStatus())(_.close())

答案 1 :(得分:1)

由于您的变量为Option[Something],因此无法调用instanceOfSomethingOpt.methodOfInstance()

取而代之的是instanceOfSomethingOpt.map(realInstance => realInstance.methodOfInstance())

在你的情况下,它是

cxn.map(realConnection => realConnection.close())

//or to make it shorter
cxn.map(_.close())

答案 2 :(得分:1)

您应该真正了解Option api

cxn.map(_.close())

是一种方式,以防close()返回您可能会遇到的事情。

cxn.foreach(_.close())

是另一种方式,如果close()做得不多(副作用)。

答案 3 :(得分:0)

val cxn = Some(repo.getConnection()) 
for (c <- cxn) yield {
   //do something with the connection
   c.close()
}

或者,您可以将getConnection包装为Either或Try,具体取决于您希望如何处理错误,请参阅http://blog.xebia.com/try-option-or-either/