Почему существуют две функции, которые делают одно и то же? Почему они должны вызываться по-разному в Kotlin?

#function #kotlin #kotlin-function-type

#функция #kotlin #kotlin-function-type

Вопрос:

 fun main() {
    fun evenFn(num: Int): Boolean {
        return num % 2 == 0
    }
    val evenFn = fun(num: Int) = num % 2 == 0
    val list = listOf(1, 2, 3, 4, 5, 6)
    println(list.filter(evenFn))
    println(list.filter { evenFn(it) })
}
  

Как получается, что я могу объявить две evenFns функции с одинаковым именем (одна хранится в переменной, а другая только что определена), и я должен вызывать их по-разному? В JavaScript это привело бы к появлению ошибки, в которой говорится, что уже существует evenFn .

Может кто-нибудь объяснить, почему компилятор evenFns обрабатывает их по-разному?

Ответ №1:

fun evenFn это метод; val evenFn это локальная переменная, которая имеет тип функции. В Kotlin (и Java, и C #, и т.д. и т.д.) разрешено иметь метод и локальную переменную с одинаковым именем в области видимости, и тип локальной переменной не влияет на эти правила.

Ответ №2:

Выполнение этого в Javascript не приведет к ошибке. В Javascript функции поднимаются на вершину области видимости.

Если бы вы написали такой код, как

 var test = function() { 
    console.log('a');
}

function test() {
    console.log('b');
}

test();
test.apply();  

второе определение функции будет поднято наверх, чтобы создать код, который читается как

 var test = function() { console.log('b'); }
var test = function() { console.log('a'); }
  

Как вы можете видеть, определение функции перезаписывается определением переменной. Следовательно, результат будет

 a
a
  

Комментарии:

1. jsbin.com/rudepokuka/edit?js , консоль , на самом деле выдает ошибку, поэтому вам нужно удалить объявление var в вашем первом операторе, потому что вы хотите переназначить его, а не повторно объявлять

Ответ №3:

Я понял это, прочитав раздел Типы функций документации kotlin. Вам нужна вызываемая ссылка на локальные функции, функции-члены, чтобы передавать их в качестве ссылок.