0

我的项目中有以下辅助方法:

def close(c: Closeable) {
  Option(c).foreach(s => Try(s.close))
}

我有一些类有一个 close 方法但没有实现 Closeable。如果我将辅助方法更改为使用结构类型,我仍然可以在这些类上使用它:

def close(c: {def close()}) {
  Option(c).foreach(s => Try(s.close))
}

然而,这引入了反射的使用,这是我想在运行时避免的。

有没有办法在不引起运行时反射的情况下使用类似于结构类型的东西?

即以同样的方式Shapeless允许对字段进行通用访问,也许隐式参数+宏可以用于以相同的方式访问方法?

4

1 回答 1

2

使用特征来实现类型类模式。当我编写原始解决方案时,边缘有点粗糙,因为我假设快速搜索将结构边界转换为上下文边界会得到比我写的更好的解释。情况似乎并非如此。下面是一个编译解决方案。

object Closeables {
  trait MyCloseable[A] {
    def myClose(a: A): Unit
}

  object MyCloseable {
    implicit object MyCanBeClosed extends MyCloseable[CanBeClosed] {
      def myClose(c: CanBeClosed) = c.nonStandardClose()
    }
  }
}

class CanBeClosed {
  def nonStandardClose(): Unit = println("Closing")
}

import Closeables._
object Test extends App {
  def functionThatCloses[A: MyCloseable](a: A) {
    implicitly[MyCloseable[A]].myClose(a)
  }
  def functionThatClosesExplicit[A](a: A)(implicit ev: MyCloseable[A]) {
    ev.myClose(a)
  }
  val c = new CanBeClosed
  functionThatCloses(c)
  functionThatClosesExplicit(c)
  functionThatCloses(c)(MyCloseable.MyCanBeClosed)
  functionThatClosesExplicit(c)(MyCloseable.MyCanBeClosed)
}

对于 functionThatClose 可以接受的每种类型的类,您必须在 MyCloseables 中定义和隐式对象。

编译器查看 functionThatCloses 中绑定的上下文,并将其转换为具有 functionThatClosesExplicitly 定义的函数。

编译器从 MyCloseables 对象的定义中“找到”隐含的“证据”并使用它。

于 2017-02-24T10:06:53.440 回答