开发者

Type of 'return this' in a Groovy @Mixin

开发者 https://www.devze.com 2023-03-31 06:20 出处:网络
I have a mixin class that bundles functionality for different types that do not share a common heritage. The mixing is applied using the @Mixin annotation, so it is handled at compile time.

I have a mixin class that bundles functionality for different types that do not share a common heritage. The mixing is applied using the @Mixin annotation, so it is handled at compile time.

Some of the mixin methods return this as the result of a method call. The problem is that the this is of the mixing type and not the type of the base class. When I want to work typed in the rest of the application a ClassCastException is thrown saying that the mixing type can not be cast to the base type.

In the example code below return this returns an object of type AMixin instead of an Object of type BaseClass.

How can I have r开发者_运维问答eturn this return an object of type BaseClass instead of an object of type 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
}


I just ran into this same situation. I solved it by setting 'this' from the concrete class into a private variable 'me' inside the concrete class and return 'me' in the Mixin classes. For example:

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

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

I feel like it's a bit kludgy, but I think it's a lot simpler than this other solution. I personally need the ability to use the same Mixin in multiple classes, and it sounds like this other proposed solution would not allow for that if you cannot assign multiple Categories to a single Mixin class.


I created the class Base added the category to the AMixin Class and the BaseClass extends from Base.....(http://groovy.codehaus.org/Category+and+Mixin+transformations)

Executed this in GroovyConsole I get

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()

EDIT just a DummyClass. I know it's very awkward that It works....I'm sure Guillaume Laforge could answer how this works...

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()
0

精彩评论

暂无评论...
验证码 换一张
取 消