6

这可能是重复的,但“as”对谷歌来说是一个令人难以置信的硬关键字,即使 SO 忽略“as”作为查询的一部分。

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

X类{
    私人价值
    公共 X(def v) {
        val=v
    }
    公共asType(C类){
        if (c == Integer.class)
            将 val 作为整数返回
        如果(c == String.class)
            将 val 作为字符串返回
    }
}

这允许类似:

new X(3) as String

工作,但无助于:

3 as X

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

X fromObject(object)

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

4

2 回答 2

6

asType正如你所说,改变Integer 接受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
于 2012-11-16T20:01:40.200 回答
2

这使功能不受 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
}
于 2012-11-16T20:33:18.793 回答