2011-01-24 14 views
3

私は、閉じられることができるものを受け取る単純なヘルパーメソッドと、前者を受け取り、関数を実行した後に「閉じる」が閉じられることを保証する関数を書くことを試みています。この構造タイプのバインドが期待どおりに機能しないのはなぜですか?

例えば、私はこのようにそれを使用したい:

closing(new FileOutputStream("/asda"))(_.write("asas")) 

マイIMPLが

object Helpers { 

    def closing[T <: { def close }](closeable: T)(action: T => Unit): Unit = 
    try action apply closeable finally closeable close 

} 

しかし、この単純なテストコンパイルしようとしている。

object Test { 

    import Helpers._ 

    closing(new FileOutputStream("/asda"))(_.write("asas")) 

} 

コンパイラを文句を言う:

推測された型引数 [java.io.FileOutputStreamは] は、メソッド閉鎖のタイプ パラメータの境界に準拠していない[T <:AnyRef {defの 近い:ユニット}]

任意のアイデアなぜですか?

答えて

11

すべての括弧なしの空の括弧とメソッドとメソッドの間Scalaでは差がある

def closing[T <: { def close() }] 

を記述する必要があります。

+0

そして、 'FileOutputStream.write'は明らかにStringを取ることができません。 String上で 'getBytes()'を呼び出します。 – Malvolio

7

種類の境界はトリッキーです。特に、Scalaはパラメータ自体に加えてパラメータリストの数を追跡します。これらを試してみてください!あなたのケースでは

class A { def f = 5 } 
class B { def f() = 5 } 
class C { def f()() = 5 } 
def useA[X <: { def f: Int }](x: X) = x.f 
def useB[X <: { def f(): Int }](x: X) = x.f 
def useC[X <: { def f()(): Int}](x: X) = x.f 

useA(new A) // This works, but what other combinations do? 

、あなたは

def closing[T <: { def close() }] ... 

P.S.をしたいですあなたが本当にこのロットを使用する予定の場合は、おそらくも

class D extends B { override def f = 6 } 
class E extends A { override def f() = 6 } 

で再生すると、あなたはそれぞれの場合に使用する必要があるuse見るべきです。

関連する問題