2014-03-02 41 views
7

我需要從Scala訪問一大組Java接口。這些接口有可能返回null方法,我想將它們轉換爲Option[T]Java隱式包裝

我發現了描述Option.apply()像這些

How to implicitly wrap a value that can be null or an array into an Scala Option

Option-izing Java getters

但是其他的答案,這需要對每個Java接口,我手動創建一個Scala包裝。像這樣...

class ScalaFoo extends JavaFoo { 
    def bar = Option(super.bar) 
} 

這看起來很凌亂,很難維護,並且容易出錯。我不希望所有額外的代碼什麼都不做,我想自動包裝所有的Java接口,所以如果改變了,包裝器也會改變。

當然,有一種方法可以用implicits做到這一點,不是嗎?

回答

3

我最近結束了這樣的事情:

object Implicits { 
    implicit class ConvertToOption[T](t: T) { 
    def optional = Option(t) 
    } 
} 

用法:

假設你有下面的Java接口:

public interface Fooable { 
    public String getFoo(); 
} 

public class Foo implements Fooable { 
    public String getFoo() { 
     return null; 
    } 
} 

在您的Scala代碼:

import Implicits._ 

val foo = new Foo() 
val myOptionalValue = foo.getFoo.optional //returns an Option[String], in this case None because getFoo returns null 
+0

謝謝serejja,那樣更好。我希望有一些方法來包裝整個界面,所以我(或其他人)不能直接調用getFoo。 – user1902291

+0

我懷疑你能用通用的方式實現你剛纔所說的。你必須手動編寫包裝 – serejja

3

我不知道有這樣做的好方法。不過,我最近在推特上看到了一個不錯的方法:

import Option.{apply => ?} 
val fooBar = ?(javaFoo.bar) 
+3

哈哈,很好。這個怎麼樣? '隱式類ConvertToOption [T](t:T){def? = Option(t)}'。結果在'foo.getFoo?' – serejja

+0

我喜歡它!減少打字。雖然我們的Clojure朋友可能會哀嘆括號的使用減少了。 :) – joescii