我最近见过几个Scala问题(例如here,here和),这些问题需要使用代理,并且在我自己的工作中不止一次出现。斯卡拉图书馆有一些代理性状(14,如果我正确计算)。Scala的代理/代表
代理类/性状通常含有大量的样板:
class FooProxy(val self: Foo) extends Foo {
// added behavior
def mymethod = ...
// forwarding methods
def method1 = self.method1
def method2(arg: String) = self.method2(arg)
...
}
trait Foo {
def method1: Unit
def method2(arg: String): Unit
}
我首先想到的是定义Proxy[T]
特点,可以作如下用途:
class FooProxy(val self: Foo) extends Proxy[Foo] {
// added behavior
def mymethod = ...
}
其中trait Proxy[T] extends T
。当然,如果没有编译器的魔力,定义Proxy
特征实际上是不可能的。
我的下一个念头,就是找一个编译器插件(这种能力显然不是在现有的编译器,或为那些14个代理特质的来源会小得多)。果然,我发现Kevin Wright's AutoProxy plugin。该插件是为了整齐地解决了代理发行,与其他使用案例(包括动态混入)沿:
class FooProxy(@proxy val self: Foo) { ... }
不幸的是,它看起来像它的工作在(2009年)十一月停滞不前。所以,我的问题是
- 是否有继续工作的AutoProxy插件?
- 这会找到它的方式进入编译器?
- 是否正在考虑其他方法?
- 最后,这是否意味着斯卡拉的一个重大缺陷?毕竟,难道不可能为给定lisp风格的宏定义一个
Proxy
特性?
特征不能有参数。你建议他们加入吗?此外,您还没有显示任何无法通过添加隐式转换来解决的问题。建立隐式转换的提议是不必要的样板吗? – 2010-08-13 19:05:37
“性状不能有参数”:愚蠢的错误,修正。 – 2010-08-13 19:33:59
隐式转换解决了类似的问题,但它们并不总是合适的(否则为什么EPFL的人在Scala库中包含这么多的代理?)。首先,他们比代表团招致更多的开销。其次,广泛使用隐式转换会伤害可维护性/可读性。 – 2010-08-13 20:02:37