groovy
groovy copied to clipboard
GROOVY-10682: Provide eachWithIndex for primitive arrays
Consider the following:
@groovy.transform.TypeChecked
void test(int[] ints) {
ints.eachWithIndex { value, index ->
println "$index: ${value.doubleValue()}"
}
}
test(0,1,2,3,4,5)
Compiler reports "[Static type checking] - Cannot find matching method java.lang.Object#doubleValue()"
eachWithIndex
is only provided for reference types, so "value" is seen as Object by the type checker.
Currently, only a draft for int arrays. Should probably also be implemented for other primitive types. There are three different approaches to do this:
- Copy-paste the implementation for each overload
- Delegate to
eachWithIndex(Iterable<T> self, Closure closure)
- Delegate to
eachWithIndex(Iterator<T> self, Closure closure)
I found option three most appealing since option 1 adds unnecessary code duplication and option 2 just calls option 3 with the iterator of self
which would add unnecessary overhead.
https://issues.apache.org/jira/browse/GROOVY-10682
This is a good start. I added some notes on the commit. You should compare to the javadoc for the T[]
variant and try to match it, except here you know the array element type so you may be able to make some small improvements.
If we're adding eachWithIndex
it appears we also need each
to satisfy STC. Can you add an each(int[])
as well?
If we're adding eachWithIndex it appears we also need each to satisfy STC. Can you add an each(int[]) as well?
The reason I did not pick this ticket up after creating it is there was no reasonable stopping point. If adding eachWithIndex
, what about each
, reverseEach
, every
and all the other T[]
extensions. I wonder if there is some way to write just one implementation and have all the primitive versions be generated automatically. @paulk-asert Do you know of such a thing? Or should we consider the possibility of allowing the T[]
or Object[]
apply to primitive arrays as well through Groovy "auto-unboxing"?
We have used code generators (hand-hacked throwaway Groovy scripts) from time to time to generate repeated patterns.
We could enhance both the dynamic and static behaviours to do some kind of array-level "auto-unboxing" for T[] and the like but we have opted not to in the past for better Java integration and (at the time) efficiency with the hand-coded primitive variants likely to be more efficient.
We also have IntArrayIterable
(and Long/Double variants). So we could write:
public static int[] eachWithIndex(int[] self, @ClosureParams(value=FromString.class, options="Integer,Integer") Closure closure) {
eachWithIndex(new IntArrayIterable(self), closure);
return self;
}
This saves work when writing the new variants but is probably slightly less efficient that the current code in this PR. This is option 2 in the original proposal but I am not sure whether IntArrayIterable was part of the original plan. It will be more efficient than falling-through via other means.
:warning: 170 God Classes were detected by Lift in this project. Visit the Lift web console for more details.
@sonatype-lift ignore
I'm trying to fight through the sonatype comments. But it is looking ready for review to me.
Could someone please approve the workflow?
LGTM
Merged, thanks! I might make some minor formatting changes post merge. I am also thinking have the TypeChecked annotation in the groovyTestCase tests in javadoc probably adds noise that doesn't need to be there. I'll ponder whether we should tweak that somehow.