5

让我们假设这个函数:

def autoClosing(f: {def close();})(t: =>Unit) = {
    t
    f.close()
}

这个片段:

val a = autoClosing(new X)(_)
a {
 println("before close")
}

可以咖喱第一部分吗?就像是:

val a = autoClosing(_) { println("before close") }

这样我就可以发送应该执行关闭的对象,并在它们上执行相同的块?

4

3 回答 3

10

是的,只要您提供占位符字符的类型,您提供的代码段就可以工作。

因此,您正在寻找的代码是:

val a = autoClosing(_: {def close();}) { println("before close") }

它可以按预期编译和工作:)。

几点注意事项:

  • AnyRef如果您为具有close方法、类似type Closeable = AnyRef {def close()}或适当接口的类型定义类型别名,则可以使您的生活更轻松。
  • 该代码片段autoClosing(_: Closeable){ ... }实际上等价于以下扩展的匿名函数:c: Closeable => autoClosing(c){ ... }. 通配符只是部分应用函数的简写。您需要给出类型_推断器的类型,不幸的是在这种情况下无法推断类型。

希望能帮助到你,

——弗拉维乌·西普西根

于 2009-12-17T11:24:45.717 回答
6

或者,您可以翻转参数:

def flip[A1, A2, B](f: A1 => A2 => B): A2 => A1 => B = x1 => x2 => f(x2)(x1)

在你的情况下:

val a = flip(autoClosing){ println("before close") }

编辑:我添加了一些大括号来帮助人类解析器:

def flip[A1, A2, B](f: (A1 => (A2 => B))): (A2 => (A1 => B)) = {
    x1 => (x2 => f(x2)(x1))
}

Flip 将函数转换(A1 => (A2 => B))(A2 => (A1 => B)).

scala> def x(x1 : Int)(x2 : Long) = 1.0 * x1 / x2
x: (Int)(Long)Double

scala> val f = flip(x)
f: (Long) => (Int) => Double = <function>

scala> val g = f(1)
g: (Int) => Double = <function>

scala> val h = g(2)
h: Double = 2.0

scala> x(1)(2)
res0: Double = 0.5
于 2009-12-17T14:15:33.917 回答
3

我很高兴看到现在有这么多人回答 Scala 问题。然而,这确实让我更难想出一些东西。这是Flaviu解决方案的替代方案

val a: {def close();} => Unit = autoClosing(_) { println("before close") }

当然,正确的解决方案是以与您将如何使用它的方式兼容的方式定义 autoClosing。

于 2009-12-17T18:55:49.873 回答