I'm learning Kotlin , and I'm trying to undetstand Ranges
I created a range of String
as follows
val alpha = "A".."Z"
I want to print this for that I wrote
for (item in alpha) println(item)
But it gives the error
Error:(13, 18) Kotlin: For-loop range must have an 'iterator()' method
Can anyone help, how to print this range?
Well you can't do it with String
s by default, since there's no iterator()
for ClosedRange<String>
, but Char
s will work directly:
val r = 'A'..'Z'
r.forEach(::println)
It will be of type CharRange
and provide the needed iterator()
.
To make your very special example work with String
s, you could define your own extension function and delegate to a Iterator<Char>
:
operator fun ClosedRange<String>.iterator(): Iterator<String> {
val charIt = (start.toCharArray().first()..endInclusive.toCharArray().first()).iterator()
return object : Iterator<String> {
override fun hasNext() = charIt.hasNext()
override fun next(): String = charIt.nextChar().toString()
}
}
Now it works as you wished. But be aware that this does not make sense for most use cases with ranges of String
.
How to print this range?
I think the only way to print this range is
println(alpha)
And you'll get
A..Z
This is how to "print" this range.
You're trying to travel through a non-iterable range, this is invalid.
Like, you cannot for (i in File("a.txt")..File("Main.java")) println(i)
.
val alpha = "A".."Z"
This is a plain range, which means it's an abstract representation of a contiguous subset within a total order. The only operation such an entity supports is answering the question "is this element within this range?", and it will be based purely on the contract of Comparable<T>
.
In your case, consider a string like "THREAD"
. Does it belong to your range? It sorts higher than "A"
but lower than "Z"
, so it does belong to it. But you probably didn't intend to iterate over it, or the infinity of all other strings belonging to your range.
What you considered as a given is actually a special case: iterable ranges. They are defined only on the three types representing integral types: IntRange
, LongRange
and CharRange
. These are the types where the subset belonging to the range can actually be enumerated and iterated over.
Can You Try This May Help You, I think you actually want 'A'..'Z' not "A".."Z"
var A = 'A'..'Z'
for(value in A){
println("$value")
}