I have the following line of code:
val fileList = dir.listFiles()
Which returns an array of java.io.File objects (File is the return type).
I am trying to do something like this:
for (file in fileList) {
// do something with each file
}
But I keep getting a message For-loop range must have an iterator() method.
I’ve tried
for (i in fileList.indices) {
//
}
and I get the same message.
What is the proper construct for this loop?
Thank you!
Randy
The error you are getting is (admittedly) not direct enough, but it's telling you that theres no iterator() method on the type "Array<File>?", which means that listFiles() may return null, over which it's hard to iterate.
The best solution is to handle the null case properly, for example
if (fileList == null) throw IllegalStateException("...")
for (filr in fileList) {…}
If for some reason you are sure that fileList will not be null, you can say
for (file in fileList!!) {...}
And get an exception if fileList happens to be null
Nicely done! Love the flow analysis.
The error message did lead me to understand that there was no iterator() available. What I didn’t understand was the root cause being a potential null value. I’m glad you are thinking about error messages as that will be an important part of the journey for developers moving to Kotlin. Maybe “For-loop requires an iterator() which is not available on nullable value”? Or something like that.
Thank you.
Randy
Have you considered the alternative option of :
for (file in fileList?) {...}
It seems like that would be an elegant way to solve this sort of issue, especially with java interop.
Yes, we did: we call it "fileList!!" (See above)
Yes, I tried that but it does not compile. The alternate:
for (file in fileList!!) {
}
does work.
I am going to use the approach of testing for null and doing something else (such as throw an exception), so that I have choice on action - log something, throw exception, pick a default, etc.
But, if fileList is null, you get an Exception at runtime, right? With the ?, I would have assumed it would just skip evaluation and hence the loop, rather than blow up.
John,
It’s my understanding that using fileList!! would mean that it would NPE if it’s null. I looked at the Java code and it can return a null. (I don’t know why or what that signifies, but that’s my reading of the code).
In this particular case, I am electing to do a null value check (==null) and then take an appropriate action. There are cases when you are certain that you won’t get a null that the !! option makes sense.
I am using Kotlin with NetKernel and I am going to review the internal code of NetKernel to figure out when and where null values could be returned and when they could not and start to either request a source code change to mark them with annotations or build an annotation file. (I have to research both of these approaches to see which I want to use).
– Randy
Often times it's much better to blow up )