なぜこの構造タイプは、期待どおりに機能しないのですか?

StackOverflow https://stackoverflow.com/questions/4787449

  •  24-10-2019
  •  | 
  •  

質問

私は、閉じられるものを受け取ることができるものと、前者を受信し、関数を実行した後に「閉じる可能性のある」を保証するいくつかの関数を受信する簡単なヘルパーメソッドを書き込もうとしています。

たとえば、私はこのようにそれを使いたいです:

  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}]に準拠しないでください。

何かアイデアはなぜですか?

役に立ちましたか?

解決

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

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

空の括弧付きの方法と括弧なしのメソッドの間には、Scalaには違いがあります。

他のヒント

タイプの境界は難しいです。特に、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 それぞれの場合に使用する必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top