Scala close方法的编译时结构类型

Scala close方法的编译时结构类型,scala,reflection,macros,shapeless,structural-typing,Scala,Reflection,Macros,Shapeless,Structural Typing,我的项目中有以下助手方法: def close(c: Closeable) { Option(c).foreach(s => Try(s.close)) } 我有一些类有close方法,但没有实现Closeable。如果我将helper方法更改为使用结构类型,我仍然可以在这些类上使用它: def close(c: {def close()}) { Option(c).foreach(s => Try(s.close)) } 然而,这引入了反射的使用,这是我希望在运行时避免

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

def close(c: Closeable) {
  Option(c).foreach(s => Try(s.close))
}
我有一些类有close方法,但没有实现Closeable。如果我将helper方法更改为使用结构类型,我仍然可以在这些类上使用它:

def close(c: {def close()}) {
  Option(c).foreach(s => Try(s.close))
}
然而,这引入了反射的使用,这是我希望在运行时避免的

有没有一种方法可以在不引发运行时反射的情况下使用类似于结构类型的东西?


也就是说,以同样的方式允许对字段的通用访问,也许隐式参数+宏可以用同样的方式访问方法?

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

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)
}
对于关闭函数可以接受的每种类型的类,必须在MyCloseTables中定义和隐式对象

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


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

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

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)
}
对于关闭函数可以接受的每种类型的类,必须在MyCloseTables中定义和隐式对象

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


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

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