简体   繁体   中英

How to print ClosedRange in Kotlin

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 .

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.

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) .

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")
}

I Loved The answers of @s1m0nw1 and @Marko Topolnik.
You can't really iterate over a ClosedRange<String>.

The literal may mislead us to think it's a ClosedRange<Char>

var range = "A".."C" // misleading literal

What you CAN do: Just a small addition: is to map the characters to Strings

val r = ('A'..'Z').map { it.toString() }//.forEach(::println)
for (letter in r){

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM