4

閉じることができるものと、前者を受け取り、関数の実行後に「閉じる」が確実に閉じられるようにする関数を受け取る単純なヘルパーメソッドを作成しようとしています。

たとえば、次のように使用したいと思います。

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

私の実装は

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 close: Unit}]

理由はありますか?

4

2 に答える 2

12

あなたは書く必要があります

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

Scala では、括弧が空であるメソッドと括弧がまったくないメソッドとの間に違いがあります。

于 2011-01-24T21:45:53.317 に答える
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() }] ...

PS本当にこれをたくさん使うつもりなら、おそらく一緒に遊ぶべきです

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

useそれぞれの場合にどれを使用する必要があるかを確認してください。

于 2011-01-24T21:47:23.127 に答える