开发者

Can I call get(i) or getFrom() on a range that is a single date in groovy?

I have a method that requires a range in groovy and I've got no problem passing in something like

new Date("01/01/1999")..new Date("01/01/1999")

But I would much prefer to pass in a single date (as Range)

When I print this out it looks good

Range range = startDate as Range

This shows up in the console

[Fri Jan 01 00:00:00 CST 1999]

But now when I try to do a .get(i) or .getFrom() it fails saying

groovy.lang.MissingMethodException: No signature of method: java.util.Date.getFrom() is applicable for argument types: () values: []
Possible solutions: getDate(), getDay(), getTime(), getYear(), before(java.util.Date), getAt(int)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
    at org.codehaus.groovy.runtime.Invok开发者_JAVA技巧erHelper$invokeMethod.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
    at Date_delegateProxy.getFr

Anyone have success trying to cast and use a single date as Range in groovy?


In Groovy the as operator calls the asType method on the object with the class you want to convert it to as an argument. DefaultGroovyMethods provides all the implementations that ship with Groovy that I'm aware of, none of which convert to Range.

You can if needed override asType to support Range, however I think most people would consider that abuse of operator overloading and such poor practice that I'm actually hesitant to provide an example. None the less, this should do what you're asking.

// Save the original asType method so that it can be called by the overridden one
final f = Date.metaClass.getMetaMethod('asType', [Class] as Class[])

// Replace the default asType method for Date objects
Date.metaClass.asType = { final Class it ->
    // For ranges convert the date into a range with the date as both the start
    // and end. For other types, use the default implementation of asType
    return it == Range? (delegate..delegate) : f.invoke(delegate, it)
}

final start = new Date()
final end   = start

assert start..end == start as Range
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜