【问题标题】:Compile time structural typing of close methodclose方法的编译时结构类型
【发布时间】:2017-02-24 09:49:15
【问题描述】:

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

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 允许对字段进行通用访问,也许隐式参数+宏可以用于以相同的方式访问方法?

【问题讨论】:

  • 我建议一般避免使用结构类型,但我个人认为运行时反射的底层使用不是问题,因为在这种情况下它不涉及放弃类型安全等.

标签: scala reflection macros shapeless structural-typing


【解决方案1】:

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

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)
}

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

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

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

【讨论】:

    猜你喜欢
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-12-05
    • 1970-01-01
    • 2011-09-07
    • 2020-09-21
    • 1970-01-01
    • 2021-07-06
    相关资源
    最近更新 更多