Question

I'm trying to write a simple helper method that receives something that can be closed and some function which receives the former and ensures the "closeable" is closed after executing the function.

For example, I want to use it like this:

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

My impl is

object Helpers {

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

}

But when trying to compile this simple test:

object Test {

  import Helpers._

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

}

The compiler complains with:

inferred type arguments [java.io.FileOutputStream] do not conform to method closing's type parameter bounds [T <: AnyRef{def close: Unit}]

Any ideas why?

Was it helpful?

Solution

You need to write

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

there is a difference in Scala between methods with empty parentheses and methods without parentheses at all.

OTHER TIPS

Type bounds are tricky. In particular, Scala keeps track of the number of parameter lists in addition to the parameters themselves. Try these out!

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?

In your case, you want

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

P.S. If you really plan on using this a lot, you probably ought also play with

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

and see which use you need to use in each case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top