2013-04-18 69 views
3

在這個問題中,我必須調用一個第三方Java庫,該庫需要一個java.util.concurrent.Future,其結果來自Scala例程返回scala.concurrent.Future,例如。Scala和Java互操作。未來

def someScalaFunction(): scala.concurrent.Future[T] 

def otherJavaMethod(arg: java.util.concurrent.Future[T]) = ... 

我想包斯卡拉,未來進入一個新的Java的未來,但有沒有辦法實現它中斷包裹斯卡拉 - 未來的方式Java的未來方法def cancel(mayInterruptIfRunning: Boolean): Boolean(否則請讓我知道)。

我該如何解決這個問題?這是我想出的辦法:

  1. 寫在包裝反正,只是忽略cancel通話(或拋出NotImplementedError
  2. 變化someScalaFunction到可能返回關閉然後將由呼叫者包裹在Scala或Java未來中。

1.的問題是某些客戶端可能依賴於cancel的正確實施,但可能不是非常關鍵。 2.會導致一個非常醜陋的api。

回答

3

請注意,cancel只會嘗試取消任務,根據Javadoc沒有保證。因此,您不必實現它來執行某些操作(取決於未來計算的內容),忽略cancel調用對於整個應用程序而言可能不是連續的。

如果您確實需要取消它,請參閱this question半解決方案。

否則,您可以使用第二種解決方案 - 藉助一些隱式轉換,您可以使它看起來更好。

object JavaInterOp { 
    implicit def f2future[F[_]](f:() => T): java.util.concurrent.Future[T] = fc(f) 
} 

這樣,導入控制您想要提供哪種轉換以及何時。

與此相關的一個問題是,它可能會進行轉換,如果您不真正需要它 - 它可能會產生令人驚訝的效果。