为什么在Kotlin中删除索引for循环?

时间:2017-07-17 12:36:26

标签: for-loop kotlin

我仍然认为"传统"使用for循环的方式非常强大,可以完全控制索引。为什么在Kotlin中删除它?

我应该如何在kotlin中使用以下java代码

for (int i = 0; i < n - 1; i++) {
   for (int j = i + 1; j < n; j++) {
   ....

14 个答案:

答案 0 :(得分:25)

它没有被删除&#34;。新语言的设计并不是从任何现有语言的特征集开始的;我们从一种没有功能的语言开始,然后开始添加以一种不错的惯用方式表达某些行为所必需的功能。到目前为止,我们还不知道C风格的任何行为。循环将是表达它的最好和最惯用的方式。

答案 1 :(得分:16)

答案是:因为他们决定将其删除。 您仍然可以使用以下语法:

for (a in 1..10) print("$a ")              // >>> 1 2 3 4 5 6 7 8 9 10

for (a in 10 downTo 1 step 2) print("$a ") // >>> 10 8 6 4 2 

了解更多信息:Ranges&amp; Loops

答案 2 :(得分:6)

我认为他们这样做的原因(“没有删除”)是因为,他们想让Kotlin更具表现力。

例如,在java中我们可以像这样创建一个for循环:

for(int x = 1; x <= 10; x++) {
   System.out.print(x);
}

你要做的就是,你要打印出从1到10 的值,就是这样。所以Kotlin决定将你的单词翻译成代码并删除不必要的冗长。

for (x in 1..10) print("$x") 

答案 3 :(得分:4)

它没有被删除。它的语法不同。 相当于Java代码:

for (int i = 0; i < n - 1; i++) {
   for (int j = i + 1; j < n; j++) {

将以这种方式写在Kotlin:

val n = 10
for (i in 0..n-2) {
    for (j in i+1..n-1) {
        println("I'm low level for loop! I just look more friendly.")
    }
}

Kotlin使用Ranges来定义循环&#39;为了简洁代码,迭代器。

答案 4 :(得分:4)

保留这些索引的另一种有用的方法就是使用Iterable方法来迭代某些东西(withIndex())。例如:

for((i, element) in myIterable.withIndex()){
    //do something with your element and the now known index, i
}

我注意到这与this回答中建议的相同,但我认为如果我们使用Iterables已经内置的方法来处理这种情况而不是再次实现它们会更好。我们可以说这也类似于forEachIndexed{} lambda:

myIterable.forEachIndexed{i, element ->
    //do something here as well
}

答案 5 :(得分:1)

没有必要在Kotlin中使用传统的for循环,因为您可以使用Kotlin lambdas使您的代码更强富有表现力可读。例如:

arrayOf(1, 2, 3).forEachIndexed { index, item -> /**TODO**/}

Kotlin只支持for-each循环, for-each循环接受任何Iterable s / Array s /该类型都有iterator运算符。

IF 您希望返回使用for-each循环表达式,您可以编写如下代码,您可以看到for-each循环将占用的代码多于lamda,这就是为什么流api&amp; amp;函数接口在中引入:

val array  = arrayOf(1, 2, 3)

for(index in array.indices){
  val item = array[index]
  // todo
}

如果,您需要回到传统的for循环,而不是使用repeat,例如:

repeat(5){index-> /**TODO**/}

答案 6 :(得分:1)

<强>为什么吗 &#34;传统&#34;循环是&#34;索引越界的原因&#34;不同的例外 收集物品的循环。

答案 7 :(得分:0)

您可以创建自己的功能来实现“完全控制索引的传统循环”。 或非传统的。 例如,混合forEachIndexed()with()count(),其中索引为1。

inline fun <T> Iterable<T>.forWithIndexed1(action: T.(index: Int) -> Unit): Int {
    var index = 0
    for (item in this) item.action(++index)
    return index
}

答案 8 :(得分:0)

这没有任何意义,因为有时您希望使用自定义步骤创建更多自定义循环,并且这种结构类型会将其从逻辑中删除

var array = ["-m", "/test/app", "-w", "us"];

for (var i = 0; i < array.length; i += 2) {
    console.log("option =" + array[i]);
    console.log("value =" + array[i+1])
}

在当前的kotlin循环中,我们失去了那里的一些简单性。

答案 9 :(得分:0)

Kotlin正在尝试实施流畅的迭代,该迭代涵盖了绝大多数循环构造。但是,我需要一个具有立即终止状态范围的传统for循环(如java),退出条件(该条件在循环体执行之前进行评估)和后执行操作(我的用例很复杂:我需要重复使用动态退出基于压缩例程和2的幂的条件。我想到了以下一般功能:

fun <S> forloop(state: S, condition: (s: S) -> Boolean, postExecution: (s: S) -> Unit, block: (s: S) -> Unit) {
  while (condition(state)) {
    block(state)
    postExecution(state)
  }
}

data class SingleIndex(var i: Int)
fun forloop(i: Int, condition: (s: SingleIndex) -> Boolean, postExecution: (s: SingleIndex) -> Unit, block: (s: SingleIndex) -> Unit) {
  forloop(SingleIndex(i), condition, postExecution, block)
}

示例here

fun main() {
    forloop(0, {it.i < 10}, {++it.i}) {
        println("forloop test: i=${it.i}")
    }

    data class State(var i: Int, var j: Int)
    forloop(State(0, 1), {it.i < 10}, {++it.i; it.j += it.i}) {
        println("forloop test: i=${it.i}, j=${it.j}")
    }
}

尽管遵循语言哲学,您仅应在极少数情况下使用它。

答案 10 :(得分:0)

在这种情况下,可以使用以下双循环:

for (i in 0 until n) {
        for (j in (i + 1) .. n) {

答案 11 :(得分:0)

for (i in generateSequence(0) { it + 2 }.takeWhile { it < array.length }) {
    // do something useful
}

答案 12 :(得分:0)

generateSequence(0) { it + 2 }.takeWhile { it < array.length }.forEach {
    // Do something useful
}

答案 13 :(得分:0)

如果要同时获取索引和值,则可以使用它。

for ((index, value) in array.withIndex()) {
    println("the element at $index is $value")
}

这很简单。

来源:Kotlin Official Documentation - Control Flow