LINUX.ORG.RU

История изменений

Исправление Legioner, (текущая версия) :

Обрати внимание на слово inline у функции myForEach. Это означает, что это не настоящая функция, а её тело будет встроено в месте вызова. И её аргументы-лямбды тоже не настоящие функциональные объекты, а их тело будет встроено в месте вызова. Поэтому возможно сделать return. Если убрать inline, то всё будет по-настоящему, но return уже не скомпилируется.

В частности вот код mapNotNull:

public inline fun <T, R : Any> Array<out T>.mapNotNull(transform: (T) -> R?): List<R> {
    return mapNotNullTo(ArrayList<R>(), transform)
}

public inline fun <T, R : Any, C : MutableCollection<in R>> Array<out T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
    forEach { element -> transform(element)?.let { destination.add(it) } }
    return destination
}

public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

Как видишь, тут все вызовы inline. В частности это означает, что для типичных функциональных конструкций никаких накладных расходов на объекты нет, в отличие от Java, результирующий байткод будет, как будто ты написал этот код обычными циклами и if-ами и это круто.

Исправление Legioner, :

Обрати внимание на слово inline у функции myForEach. Это означает, что это не настоящая функция, а её тело будет встроено в месте вызова. И её аргументы-лямбды тоже не настоящие функциональные объекты, а их тело будет встроено в месте вызова. Поэтому возможно сделать return. Если убрать inline, то всё будет по-настоящему, но return уже не скомпилируется.

В частности вот код mapNotNull:

public inline fun <T, R : Any> Array<out T>.mapNotNull(transform: (T) -> R?): List<R> {
    return mapNotNullTo(ArrayList<R>(), transform)
}

public inline fun <T, R : Any, C : MutableCollection<in R>> Array<out T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
    forEach { element -> transform(element)?.let { destination.add(it) } }
    return destination
}

public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

Как видишь, тут все вызовы inline. В частности это означает, что для типичных функциональных конструкций никаких накладных расходов на объекты нет, в отличие от Java, и это круто.

Исходная версия Legioner, :

Обрати внимание на слово inline у функции myForEach. Это означает, что это не настоящая функция, а её тело будет встроено в месте вызова. И её аргументы-лямбды тоже не настоящие функциональные объекты, а их тело будет встроено в месте вызова. Поэтому возможно сделать return. Если убрать inline, то всё будет по-настоящему, но return уже не скомпилируется.