首页 文章

我如何使用groovy的AS关键字

提问于
浏览
5

这可能是重复的,但“as”是谷歌的一个难以置信的硬关键词,甚至是S.O.忽略“as”作为查询的一部分 .

所以我想知道如何实现一个反复支持“as”的类 . 对于示例类:

class X {
    private val
    public X(def v) {
        val=v
    }
    public asType(Class c) {
        if (c == Integer.class)
            return val as Integer
        if(c == String.class)
            return val as String
    }
}

这允许类似于:

new X(3) as String

工作,但没有帮助:

3 as X

我可能不得不以某种方式在String和Integer上附加/修改“asType”,但我觉得这样的任何更改都应该局限于“X”类...... X类是否可以实现如下方法:

X fromObject(object)

或者以某种方式修改X中的String / Integer类 . 这看起来很难,因为在实际使用X之前它不会执行X中的任何代码...如果我第一次使用X是“3作为X”,那么X将得到在Groovy尝试调用之前有机会覆盖Integer的asType吗?

2 回答

  • 2

    正如您所说,将Integer的 asType 方法更改为接受 X 作为一种新类型的转换(特别是在不破坏现有功能的情况下)并不容易 .

    我能想到的最好的事情就是:

    Integer.metaClass.toX = { -> new X( delegate ) }
    

    然后你可以打电话:

    3.toX()
    

    我无法想象 3 as X 怎么办 - 正如你所说,另一种方式; new X('3') as Integer 相对容易 .


    实际上,你可以这样做:

    // Get a handle on the old `asType` method for Integer
    def oldAsType = Integer.metaClass.getMetaMethod( "asType", [Class] as Class[] )
    
    // Then write our own
    Integer.metaClass.asType = { Class c ->
      if( c == X ) {
        new X( delegate )
      }
      else {
        // if it's not an X, call the original
        oldAsType.invoke( delegate, c )
      }
    }
    
    3 as X
    
  • 5

    这样可以将功能保留在Integer类型之外,并最大限度地减少效果的范围(根据您要查找的内容,这是好还是坏) .

    此类别将从Integer侧应用asType .

    class IntegerCategory {
        static Object asType(Integer inty, Class c) {
            if(c == X) return new X(inty)
            else return inty.asType(c)
        }
    }
    
    use (IntegerCategory) { 
        (3 as X) instanceof X
    }
    

相关问题