2017-05-03 48 views
2

我最近改變了很多我的Scala代碼,以避免使用null實例化變量,而是使用Option。例如,我以前有:使用Scala選項

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

+0

你爲什麼不能用'VAL CXN嘗試= repo.getConnection()'在這種情況下?這裏真正的問題是使用var並將其設置爲null/None,然後在其中輸入實際值。使用'Option'並不能改善這一點。 – puhlen

+0

原因是,由於我的代碼的設計,cxn需要是一個全局變量,並且在稍後纔會設置。事實上,當cxn初始化時,repo對象還沒有創建,並且由於我正在使用的技術,我相信這是必需的。 – hayfreed

+3

你不想要選項,你需要一個懶惰的val你的描述的問題。 – pedrofurla

回答

1

由於您的變量是Option[Something],你不能叫instanceOfSomethingOpt.methodOfInstance()

而是做instanceOfSomethingOpt.map(realInstance => realInstance.methodOfInstance())

在你的情況,這將會是

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

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

你真的應該給看看Optionapi

cxn.map(_.close()) 

是一種方式,以防close()返回您可能會被注意的事情。

cxn.foreach(_.close()) 

是另一種方式,如果close()沒有做太多(副作用)。

2

您有幾個選擇。 (很抱歉的雙關語)。最直接的可能是...

cxn.map(_.close()) 

但是,也許你需要做別的事情,如果cxnNone。然後,你可以做這樣的事情......

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

'.foreach'可能是最合適的,因爲OP似乎不關心'.close'返回值。另外,而不是'.fold',它可以使用'.map(stuff)。getOrElse(otherStuff)' – pedrorijo91

+0

@ pedrorijo91,好點。可以認爲'.getOrElse()'更容易理解,但我傾向於更喜歡'.fold()()',因爲它的簡潔性和我認爲更多人應該知道的習慣用法。我真正應該包括的是[鏈接到ScalaDocs頁面](http://www.scala-lang.org/api/current/scala/Option.html),其中可以找到所有的各種解決方案。 – jwvh

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

或者你可以用與無論是的getConnection或取決於您希望如何處理錯誤看到http://blog.xebia.com/try-option-or-either/