LEMUEL  ADANE
LEMUEL ADANE

Reputation: 8818

Kotlin: For-loop must have an iterator method - is this a bug?

I have the following code:

public fun findSomeLikeThis(): ArrayList<T>? {
    val result = Db4o.objectContainer()!!.queryByExample<T>(this as T) as Collection<T>
    if (result == null) return null
    return ArrayList(result)
}

If I call this like:

var list : ArrayList<Person>? = p1.findSomeLikeThis()

for (p2 in list) {
    p2.delete()
    p2.commit()
}

It would give me the error:

For-loop range must have an 'iterator()' method

Am I missing something here?

Upvotes: 41

Views: 39048

Answers (4)

Sumanth Hegde
Sumanth Hegde

Reputation: 81

try

for(p2 in 0 until list.count()) {
    ...
    ...
} 

Upvotes: 5

Dhiraj Gupta
Dhiraj Gupta

Reputation: 10484

This can also happen in Android when you read from shared preferences and are getting a (potentially) nullable iterable object back like StringSet. Even when you provide a default, the compiler is not able to determine that the returned value will never actually be null. The only way I've found around this is by asserting that the returned expression is not null using !! operator, like this:

val prefs = PreferenceManager.getDefaultSharedPreferences(appContext)
val searches = prefs.getStringSet("saved_searches", setOf())!!
for (search in searches){
    ...
}

Upvotes: 0

Linh
Linh

Reputation: 60923

I also face this problem when I loop on some thing it is not an array.
Example

fun maximum(prices: Array<Int>){
    val sortedPrices = prices.sort()
    for(price in sortedPrices){ // it will display for-loop range must have iterator here (because `prices.sort` don't return Unit not Array)

    }
}

This is different case to this question but hope it help

Upvotes: 0

naixx
naixx

Reputation: 1174

Your ArrayList is of nullable type. So, you have to resolve this. There are several options:

for (p2 in list.orEmpty()) { ... }

or

 list?.let {
    for (p2 in it) {

    }
}

or you can just return an empty list

public fun findSomeLikeThis(): List<T> //Do you need mutable ArrayList here?
    = (Db4o.objectContainer()!!.queryByExample<T>(this as T) as Collection<T>)?.toList().orEmpty()

Upvotes: 68

Related Questions