SMM*_*MMH 4 loops iterable standard-library kotlin
与 Java 中一样,任何对象都Iterable
可以在增强的 for 循环中使用。我认为 Kotlin 也同样如此,直到我发现事实kotlin.collections.Map
并非如此Iterable
。
来自标准库源代码:
public interface Map<K, out V> {
// ....
Run Code Online (Sandbox Code Playgroud)
如果不是,那么这样的事情怎么可能?:
val map: Map<String, Int> = HashMap()
// ...
for ((s, i) in map) {
println(s)
println(i)
// works perfectly
}
Run Code Online (Sandbox Code Playgroud)
最后,是否可以制作支持此语法的自定义类?如果是这样,怎么办?
Kotlin for 循环是按约定定义的:
Kotlin 中的某些语法形式是按约定定义的,这意味着它们的语义是通过一种语法形式的语法扩展为另一种语法形式来定义的。
在 的情况下for(VarDecl in C) Body
,它扩展为的语法形式是:
when(val $iterator = C.iterator()) {
else -> while ($iterator.hasNext()) {
val VarDecl = $iterator.next()
<... all the statements from Body>
}
Run Code Online (Sandbox Code Playgroud)
如规范中所指定。
不需要特定的接口,只需要重载解析为,和找到适当的operator
重载。作为一个极端的例子,这可以编译!iterator()
hasNext()
next()
fun main() {
for (s in Foo()) { // no error here!
}
}
class Foo {
operator fun iterator(): Bar = Bar()
}
class Bar {
operator fun hasNext() = false
operator fun next() = ""
}
Run Code Online (Sandbox Code Playgroud)
在你的情况下,存在一个扩展iterator
函数Map
:
operator fun <K, V> Map<out K, V>.iterator(): Iterator<Entry<K, V>>
Run Code Online (Sandbox Code Playgroud)
和MutableMap
:
@JvmName("mutableIterator")
operator fun <K, V> MutableMap<K, V>.iterator(): MutableIterator<MutableEntry<K, V>>
Run Code Online (Sandbox Code Playgroud)
该iterator
方法不必在中声明Map
- 只要重载解析可以解析它,for 循环就可以工作。这同样适用于next
和hasNext
。
因此,要使您自己的类使用 for 循环,您至少需要声明:
operator fun iterator(): Iterator<Something>
Run Code Online (Sandbox Code Playgroud)
但我仍然建议您实现Iterable
,因为这样您就可以Iterable
免费获得所有扩展功能:)
归档时间: |
|
查看次数: |
691 次 |
最近记录: |