3

私は Programming Scala の本 (Martin Odersky、Lex Spoon、Bill Venners ed1 著) を読んでいて、ある特徴に出会いました。私が興味深いと思うセクションは、積み重ね可能な変更です。使用例は

abstract class IntQueue {
  def get(): Int
  def put(x: Int)
}
trait Incrementing extends IntQueue {
  abstract override def put(x: Int) {super.put(x+1)}
}  
trait Filtering extends IntQueue{
  abstract override def put(x: Int){
    if(x >=0) super.put(x)
  }
}

したがって、提供されている例には、次のように IntQueue を拡張する具体的なクラス「BasicIntQueue」があります

import scala.collection.mutable.ArrayBuffer

class BasicIntQueue extends IntQueue{
  private val buf = new ArrayBuffer[Int]
  def get() = buf.remove(0)
  def put(x: Int) {buf +=x}
}

scala> val queue = (new BasicIntQueue with Incrementing with Filtering)

scala> queue.put(-1);queue.put(0);queue.put(1)

scala> queue.get() = 1

したがって、この例では、フィルタリングとインクリメントの両方が「連鎖」され、要素がキューに「入れられる」前に実行されることを示しています。

これを Groovy でどのように実現できるかを考えていました。おそらく、Groovy のメタ プログラマビリティのために必要ないのでしょう。

4

2 に答える 2

3

Groovy 2.3以降、 Groovy はtraitスタック可能な traitをサポートします。したがって、実装は Scala とまったく同じように見えます。

interface IntQueue {
    Integer get()
    void put(Integer x)
}

trait Incrementing implements IntQueue {
    void put(Integer x) { super.put(x+1) }
}  
trait Filtering implements IntQueue {
    void put(Integer x) { if(x >= 0) super.put(x) }
}

class BasicIntQueue implements IntQueue {
    private buf = new ArrayList<Integer>()
    Integer get() { buf.remove(0) }
    void put(Integer x) { buf << x}
    String toString() { buf.toString() }
}

def queue = new BasicIntQueue().withTraits Incrementing, Filtering

queue.put(-1)
queue.put(0)
queue.put(1)
assert queue.get() == 1
于 2014-04-28T18:37:43.173 に答える
2

Groovy には、スタック可能なトレイトを行うための自然な方法がありません。カテゴリはトレイト機能の一部を提供しますが、メソッドのオーバーライドにはあまり適しておらず、多くのメタクラス マジックなしではスタックできません。

@DelegateGroovy でのより良いアプローチは、注釈と共にデコレータ パターンを適用することです。各「特性」は、適切な動作をオーバーライドし、「スーパー」クラスに委譲できます。例:

interface IntQueue {
    def get()
    def put(x)
}

class Incrementing implements IntQueue {
    @Delegate IntQueue self
    def put(x) {
        self.put(x+1)
    }
}

class Filtering implements IntQueue {
    @Delegate IntQueue self
    def put(x) {
        if (x >= 0) {
            self.put(x)
        }
    }
}

class BasicIntQueue implements IntQueue {
  private buf = []
  def get() { buf.pop() }
  def put(x) { buf << x }
}

次に、次のように目的の特性を持つオブジェクトを構築できます。

def q = new Filtering(self: new Incrementing(self: new BasicIntQueue()))
于 2013-04-20T04:29:10.777 に答える