Конечно. Вот некоторый код, который я написал, чтобы добавить интерфейс к функции. Это не совсем то, что вы хотите, но я думаю, что это может быть адаптировано с небольшими изменениями. Самое сложное изменение - invoke
, где вам нужно изменить вызванный метод на тот, который получен в результате отражения. Кроме того, вам нужно позаботиться о том, чтобы полученный метод, который вы обрабатываете, был apply
. Кроме того, вместо f
вы бы использовали целевой объект. Вероятно, это должно выглядеть примерно так:
def invoke(proxy: AnyRef, method: Method, args: Array[AnyRef]) = method match {
case m if /* m is apply */ => target.getClass().getMethod("name", /* parameter type */).invoke(target, args: _*)
case _ => /* ??? */
}
В любом случае, вот код:
import java.lang.reflect.{Proxy, InvocationHandler, Method}
class Handler[T, R](f: Function1[T, R])(implicit fm: Manifest[Function1[T, R]]) extends InvocationHandler {
def invoke(proxy: AnyRef, method: Method, args: Array[AnyRef]) = method.invoke(f, args: _*)
def withInterface[I](implicit m: Manifest[I]) = {
require(m <:< manifest[Function1[T, R]] && m.erasure.isInterface)
Proxy.newProxyInstance(m.erasure.getClassLoader(), Array(m.erasure), this).asInstanceOf[I]
}
}
object Handler {
def apply[T, R](f: Function1[T, R])(implicit fm: Manifest[Function1[T, R]]) = new Handler(f)
}
И используйте это так:
trait CostFunction extends Function1[String, Int]
Handler { x: String => x.length } withInterface manifest[CostFunction]
Использование там "манифеста" помогает с синтаксисом. Вы могли бы написать это так:
Handler({ x: String => x.length }).withInterface[CostFunction] // or
Handler((_: String).length).withInterface[CostFunction]
Можно также удалить манифест и использовать вместо него classOf с некоторыми изменениями.