Почему в Котлине был удален индексированный цикл for?
Я все еще думаю, что "традиционный" способ использования цикла for очень мощный с полным контролем индекса. Почему его убрали в Котлине?
что мне делать в Котлине со следующим java-кодом
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
....
8 ответов
ответ: потому что они решили убрать его. Вы все еще можете использовать следующий синтаксис:
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
Он не был "удален". Дизайн нового языка не начинается с набора функций любого существующего языка; мы начинаем с языка, который не имеет функций, и начинаем добавлять функции, которые необходимы для выражения определенного поведения приятным и идиоматическим способом. До сих пор мы не знаем о каком-либо поведении, для которого цикл " for " В стиле C был бы самым приятным и идиоматическим способом его выражения.
Я думаю, что причина, по которой они сделали это таким образом ("не удалены"), заключается в том, что они хотели сделать Котлин более выразительным.
например, в java мы можем создать for-loop следующим образом:
for(int x = 1; x < 10; x = x + 1) {
System.out.print(x);
}
все, что вы пытаетесь сделать, это то, что вы хотите распечатать значения от 1 до 10, вот и все. Поэтому Котлин решил перевести ваши слова в код и удалить ненужную многословность.
for (x in 1..10) print("$x")
он не был удален. Просто у него другой синтаксис. Эквивалент Java-кода:
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
было бы написано в Котлине таким образом:
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.")
}
}
Котлин использует диапазоны определить итераторы циклов для краткости кода.
еще один полезный способ сохранить эти индексы белыми, повторяя что-то (типа Iterable, то есть), использовать withIndex()
метод. Например:
for((i, element) in myIterable.withIndex()){
//do something with your element and the now known index, i
}
Это я заметил достигает того же, что и то, что предложил в этой ответ, но я думаю, что лучше использовать уже встроенный метод Iterables для таких ситуаций, а не реализовывать их снова. Это мы могли бы сказать, также похож на forEachIndexed{}
лямбда:
myIterable.forEachIndexed{i, element ->
//do something here as well
}
нет необходимости использовать традиционные for
цикл в Kotlin, потому что вы можете использовать Kotlin lambdas, чтобы сделать ваш код более выразительных и читабельный. например:
arrayOf(1, 2, 3).forEachIndexed { index, item -> /**TODO**/}
Котлин поддерживает только для каждого петли,
The для каждого цикл принимает любой Iterable
s/Array
s / тип имеет iterator
оператора.
если вы хотите использовать для каждого петли выражение, Вы можете написать код, как показано ниже, и вы увидите, что для каждого цикл займет больше кода, чем lamda, поэтому API потока и функциональный интерфейс были введены в java-8:
val array = arrayOf(1, 2, 3)
for(index in array.indices){
val item = array[index]
// todo
}
если вам нужно вернуться к традиционному for
цикл вы можете использовать repeat
вместо этого, например:
repeat(5){index-> /**TODO**/}
вы можете создать собственную функцию для того чтобы осуществить "традиционный цикл с полным контролем индекса".
Или нетрадиционным.
Например, гибридные 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
}
почему? "Традиционный" цикл является причиной исключения "index out of bounds" в отличие от цикл по элементам коллекции.