代理人/代表在Scala [英] Proxies / delegates in Scala

查看:89
本文介绍了代理人/代表在Scala的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看到过几个Scala问题(例如 here 此处 here ),它要求使用代理,并且在我自己的工作中出现了不止一次。 Scala图书馆有许多代理特征(14,如果我正确计数)。



代理类/特征通常包含大量样板:

  class FooProxy(val self:Foo)extends Foo {
//添加行为
def mymethod = ...

//转发方法
def method1 = self.method1
def method2(arg:String)= self.method2(arg)
...
}

trait Foo {
def method1:Unit
def method2(arg:String):Unit
}

我的第一个想法是定义一个代理[T] trait,可以使用如下:

  class FooProxy(val self:Foo)extends Proxy [Foo] {
//添加行为
def mymethod =。
}

其中 trait Proxy [T] extends T 。当然,实际上并没有可以定义 Proxy trait而没有编译器魔术。



我的下一个想法是看对于编译器插件(这种能力显然不在现有的编译器中,或者这些14个代理特征的来源将会更小)。果然,我发现 Kevin Wright的AutoProxy插件。该插件旨在解决代理问题,以及其他用例(包括动态混合):

  class FooProxy(@代理val self:Foo){...} 

不幸的是,它看起来像是停止工作十一月(2009)。所以,我的问题是


  1. AutoProxy插件是否继续工作?

  2. 进入编译器的方式?

  3. 是否考虑其他方法?

  4. 最后,这是Scala中的一个重大弱点吗?毕竟,是不是可以定义一个代理 trait给定的lisp风格的宏?


解决方案

四个问题,四个答案


  1. 家庭必须先到!另外还有其他人参与编译器插件中合成方法的一般问题。


  2. 如果是这样,它很可能是以不同的形式不使用注释。


  3. 我不知道任何等效的插件,虽然其中一个Scala GSOC候选项目部分基于我的自动代码。然而,有一个非常干净的解决方案在大多数情况下可以工作,并且根本不需要编译器插件:您定义从FooProxy到Foo的隐式转换,只需返回 self member;这样会让你得到最大的方式。该方法的主要问题是,如果您需要使用Java中的代码,它将使生活变得更加困难,在速度/内存方面可能效率较低,这是您必须注意的另一个原因。 p>


  4. 令人沮丧的部分是几乎所有必要的逻辑已经在编译器中可用,它用于混合,所以真的应该是处理任务的优雅方式。



I've seen several Scala questions recently (e.g. here, here, and here) that called for the use of proxies, and it's come up more than once in my own work. The Scala library has a number of proxy traits (14, if I counted correctly).

Proxy classes/traits usually contain lots of boilerplate:

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
}

My first thought was to define a Proxy[T] trait that could be used as follows:

class FooProxy(val self: Foo) extends Proxy[Foo] {
   // added behavior
   def mymethod = ...
}

where trait Proxy[T] extends T. Of course, it's not actually possible to define the Proxy trait without compiler magic.

My next thought was to look for a compiler plugin (such a capability clearly isn't in the existing compiler, or the sources for those 14 proxy traits would be much smaller). Sure enough, I found Kevin Wright's AutoProxy plugin. The plugin is intended to solve the proxy issue neatly, along with other use cases (including dynamic mixins):

class FooProxy(@proxy val self: Foo) { ... }

Unfortunately, it looks like work on it stalled in November (2009). So, my questions are

  1. Is there continuing work on the AutoProxy plugin?
  2. Will this find its way into the compiler?
  3. Are any other approaches being considered?
  4. Finally, does this point to a significant weakness in Scala? After all, wouldn't it be possible to define a Proxy trait given lisp-style macros?

解决方案

Four questions, four answers

  1. I am, though family has to come first! Plus others are involved in looking at the general issue with synthesizing methods in a compiler plugin.

  2. If so, it will most likely be in a different form, perhaps without using annotations.

  3. I don't know of any equivalent plugins, although one of the Scala GSOC candidate projects was based partly on my autoproxy code. There is, however, one very clean solution that will work in most cases and doesn't need a compiler plugin at all: You define an implicit conversion from FooProxy to Foo that simply returns the self member; this will get you most of the way there. The main issues with the approach are that it'll make life harder if you need to use your code from Java, it may be less efficient in terms of speed/memory, and it's another imlicit that you have to be aware of.

  4. The frustrating part is that almost all of the necessary logic is already available in the compiler, and it's used for mixins, so there really should be an elegant way of handling the task.

这篇关于代理人/代表在Scala的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆