Pab*_*oni 4 scala structural-typing
我正在尝试编写一个简单的辅助方法,它接收可以关闭的东西和一些接收前者的函数,并确保在执行函数后关闭"closeable".
例如,我想像这样使用它:
closing(new FileOutputStream("/asda"))(_.write("asas"))
Run Code Online (Sandbox Code Playgroud)
我的意思是
object Helpers {
def closing[T <: { def close }](closeable: T)(action: T => Unit): Unit =
try action apply closeable finally closeable close
}
Run Code Online (Sandbox Code Playgroud)
但是在尝试编译这个简单的测试时:
object Test {
import Helpers._
closing(new FileOutputStream("/asda"))(_.write("asas"))
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
推断类型参数[java.io.FileOutputStream]不符合方法结束的类型参数bounds [T <:AnyRef {def close:Unit}]
有什么想法吗?
Deb*_*ski 12
你需要写
def closing[T <: { def close() }]
Run Code Online (Sandbox Code Playgroud)
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?
Run Code Online (Sandbox Code Playgroud)
在你的情况下,你想要
def closing[T <: { def close() }] ...
Run Code Online (Sandbox Code Playgroud)
PS如果你真的打算大量使用它,你可能也应该玩
class D extends B { override def f = 6 }
class E extends A { override def f() = 6 }
Run Code Online (Sandbox Code Playgroud)
并查看use
每种情况下需要使用的内容.