How to print ClosedRange in Kotlin

2019-06-10 18:46发布

问题:

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?

回答1:

Well you can't do it with Strings by default, since there's no iterator() for ClosedRange<String>, but Chars 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 Strings, 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.



回答2:

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



回答3:

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.



回答4:

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


标签: kotlin