Тип «вернуть это» в Groovy @Mixin - PullRequest
2 голосов
/ 29 августа 2011

У меня есть класс mixin, который объединяет функциональность для разных типов, которые не имеют общего наследия. Микширование применяется с помощью аннотации @Mixin, поэтому оно обрабатывается во время компиляции.

Некоторые из методов mixin возвращают this в результате вызова метода. Проблема в том, что this относится к типу микширования, а не к типу базового класса. Когда я хочу работать, набираемый в остальной части приложения, выдается исключение ClassCastException о том, что тип смешивания не может быть приведен к базовому типу.

В приведенном ниже примере кода return this возвращает объект типа AMixin вместо объекта типа BaseClass.

Как я могу return this вернуть объект типа BaseClass вместо объекта типа AMixin?

class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in childred) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
class BaseClass {
  boolean isWhatiWant
  List<baseClass> children
}

Ответы [ 2 ]

3 голосов
/ 06 октября 2011

Я просто столкнулся с такой же ситуацией.Я решил это, установив «this» из конкретного класса в личную переменную «me» внутри конкретного класса и вернул «me» в классах Mixin.Например:

class MyMixin {
    def mixinMethod() {
        // do stuff
        return me
    }
}

@Mixin(MyMixin)
class MyConcreteClass {
    private MyConcreteClass me
    MyConcreteClass() {
        me = this
    }
}

Я чувствую, что это немного глупо, но я думаю, что это намного проще, чем это другое решение.Мне лично нужна возможность использовать один и тот же Mixin в нескольких классах, и похоже, что это другое предлагаемое решение не позволит этого, если вы не можете назначить несколько категорий одному классу Mixin.

2 голосов
/ 29 августа 2011

Я создал класс Base, добавил категорию в класс AMixin, а BaseClass расширяется от Base ..... (http://groovy.codehaus.org/Category+and+Mixin+transformations)

Выполнено это в GroovyConsole, я получаю

BaseClass @ 39c931fb

class Base {
     boolean isWhatIwant
     List<BaseClass> children
}

@Category(Base)
class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in children) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
public class BaseClass extends Base {

}

def b = new BaseClass(isWhatIwant:true)
println b.getWhatIWant()

РЕДАКТИРОВАТЬ просто DummyClass. Я знаю, это очень неловко, что это работает .... Я уверен, Гийом Лафорж мог бы ответить, как это работает ...

class DummyClass {

}

@Category(DummyClass)
class AMixin {

  def getWhatIWant(){
    if(isWhatIwant){
      return this
    } else {
      getChildWhatIWant()
    }
  }

  def getChildWhatIWant(){
    for (def child in children) {
        def whatIWant = child.getWhatIWant()
        if (whatIWant) {
            return whatIWant
        }
    }
    return null
  }
}


@Mixin(AMixin)
public class BaseClass extends DummyClass {
     boolean isWhatIwant
     List<BaseClass> children
}

def b = new BaseClass(isWhatIwant:true)
println b.getWhatIWant()
...