【问题标题】:Groovy Mixin use method of mixed classGroovy Mixin 混合类的使用方法
【发布时间】:2013-05-18 00:56:45
【问题描述】:

考虑一个混合类

class StringPlusMixin {
  String plus(String other) {
    return toString() + other
  }
}

还有他的用例

@Mixin(StringPlusMixin)
class POGO {
  String descr
  String toString(){
    return descr
  }
}

有没有办法让SringPlusMixin 使用POGO#toString() 而不是SringPlusMixin#toString()?

实际输出为:

POGO pogo = new POGO(descr: "POGO description");
System.out.println(pogo + "Some message."); //StringPlusMixin@f410f8 Some message.

我正在考虑使用这个 mixin,因为 Groovy 默认的 instance + String 是尝试调用 plus() 方法。我在几个 Java 类中使用了我的POGO,并试图不需要更改所有消息以使用toString()。

【问题讨论】:

    标签: groovy mixins


    【解决方案1】:

    在 POGO 中使用@Delegate 转换。

    @Mixin(StringPlusMixin)
    class POGO {
      @Delegate String descr
      String toString(){
        return descr
      }
    }
    

    由于descr 归 POGO 所有,在运行时使用 descr 被委托给 POGO 的所有者。

    【讨论】:

    • 我对此进行了测试,效果很好!对我来说,如果StringPlusMixin 直接使用descr 是有意义的。我仍然不清楚为什么使用 Groovy 属性中的 @Delegate 开始调用 POGO 的 toString() 而不是 StringPlusMixin 的 toString()。例如,如果我将方法更改为:String toString(){ return "[$descr]" },这仍然有效。
    • 我明白,它在这里完美运行,因为@Delegate 覆盖了所有内容(甚至是 Mixins)并尝试调用 String 类的默认 toString()。但在这种情况下,toString 已被 POGO 覆盖,它会在运行时使用它吗?
    【解决方案2】:

    反思?另外,我通过将方法设为静态并将子对象作为第一个参数传递,将您的类变成了一个类别。

    更新:根据 cmets,从 mixin 方法中移除类型

    import org.codehaus.groovy.runtime.InvokerHelper as Invoker
    
    class StringPlusMixin {
      static String plus(pogo, String other) {
        def toString = pogo.class.declaredMethods.find { it.name == "toString" }
        return toString.invoke(pogo) + other
      }
    }
    
    
    @Mixin(StringPlusMixin)
    class POGO {
      String descr
      String toString(){
        return descr
      }
    }
    
    
    pogo = new POGO(descr: "POGO description")
    assert pogo + " Some message." == "POGO description Some message."
    

    【讨论】:

    • Mixin(StringPlusMixin) 这样不就是和POGO紧密耦合了吗?如果我有 POGO1 使用这个 Mixin,我将如何处理?用 POGO 和 POGO1 创建一个 Category 接口来实现它?
    • 这个想法是将StringPlusMixin应用于任何类,因此创建一个紧密耦合的静态方法对我没有帮助,但感谢您的回答。
    • @SérgioMichels 该类别可以是动态的。更新了代码。
    • @WillP 您的 mixin 实现有什么理由将 plus 方法设为静态?看着in the javadocs 似乎只是公开的,我错过了什么?
    • @SérgioMichels Mixin 类被视为一个类别。看看这个sample。
    猜你喜欢
    • 1970-01-01
    • 2011-07-02
    • 2013-05-05
    • 2011-01-30
    • 2010-09-30
    • 2011-11-06
    • 2013-06-01
    • 2011-01-30
    • 1970-01-01
    相关资源
    最近更新 更多