Reputation: 351
If I try to compile this code...
fun main(args: Array<String>) {
for (i in 1.0..2.0) {
println(i)
}
}
... I get the error saying
For-loop range must have an 'iterator()' method
If I add a step
...
fun main(args: Array<String>) {
for (i in 1.0..2.0 step .5) {
println(i)
}
}
... then I get a new error instead:
Kotlin: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public infix fun CharProgression.step(step: Int): CharProgression defined in kotlin.ranges
public infix fun IntProgression.step(step: Int): IntProgression defined in kotlin.ranges
public infix fun LongProgression.step(step: Long): LongProgression defined in kotlin.ranges
public infix fun UIntProgression.step(step: Int): UIntProgression defined in kotlin.ranges
public infix fun ULongProgression.step(step: Long): ULongProgression defined in kotlin.ranges
How then can I use doubles in a range? The post Ranges Reloaded on The Kotlin Blog shows that using Double ranges is fine. I don't know what's wrong with mine.
Upvotes: 25
Views: 20004
Reputation: 141
In some cases you can use repeat
loop. For example in this situation you can count how many time this the loop will repeat. so...
fun main() {
var startNum = 1.0
repeat(4) {
startNum += 0.5
//TODO something else
}
}
Upvotes: 4
Reputation: 31234
As of Kotlin 1.1, a ClosedRange<Double>
"cannot be used for iteration" (rangeTo()
- Utility functions - Ranges - Kotlin Programming Language).
You can, however, define your own step
extension function for this. e.g.:
infix fun ClosedRange<Double>.step(step: Double): Iterable<Double> {
require(start.isFinite())
require(endInclusive.isFinite())
require(step > 0.0) { "Step must be positive, was: $step." }
val sequence = generateSequence(start) { previous ->
if (previous == Double.POSITIVE_INFINITY) return@generateSequence null
val next = previous + step
if (next > endInclusive) null else next
}
return sequence.asIterable()
}
Although you can do this if you are working with money you shouldn't really be using Double
(or Float
). See Java Practices -> Representing money.
Upvotes: 23
Reputation: 31710
According to the documentation for ranges:
Floating point numbers (
Double
,Float
) do not define theirrangeTo
operator, and the one provided by the standard library for generic Comparable types is used instead:
public operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>
The range returned by this function cannot be used for iteration.
You will have to use some other kind of loop since you can't use ranges.
Upvotes: 3