Объявление функции Kotlin: знак равенства перед фигурными скобками
В Kotlin синтаксис объявления функции позволяет писать знак равенства перед фигурными скобками. Рассмотрим эти два примера:
Без
=
знак:fun foo() { bar() println("baz") }
Код внутри тела исполняется простым вызовом
foo()
,С
=
знак:fun foo() = { bar() println("baz") }
Здесь, когда
foo()
называется, ничего не происходит, но для выполнения тела можно написатьfoo()()
,
В чем разница в этих двух декларациях и почему они ведут себя по-разному?
Этот вопрос, хотя и не имеющий большого значения, преднамеренно задается и на него отвечает автор, потому что уже было опубликовано несколько вопросов, где у людей возникали проблемы из-за неправильных определений функций.
1 ответ
Несмотря на визуальное сходство, идея этих двух объявлений совершенно другая.
Объявление функции без знака равенства
Unit
функция возврата (аналогично Javavoid
функции).Внутри фигурных скобок находится его тело, которое выполняется прямо при вызове функции. Функция может быть переписана с
Unit
явно указано:fun foo(): Unit { bar() println("baz") return Unit }
Котлин не требует оператора возврата и явного типа возврата для
Unit
-возвратные функции, и оба обычно опускаются.Объявление функции со знаком равенства является функцией с одним выражением, и она просто возвращает то, что находится справа от знака равенства.
Более простой пример:
fun getInt() = 1
это просто более короткая формаfun getInt(): Int { return 1 }
,В
foo
, выражение является лямбда- выражением, и оно только возвращается, но не выполняется.Тип возврата
foo
является() -> Unit
, сама функция, и, таким образом,foo
является функцией высшего порядка.Без синтаксического сахара и с явным типом,
foo
может быть переписан какfun foo(): () -> Unit { val result: () -> Unit = { bar(); println("baz") } return result }
Что касается использования, функция, которая
foo
возврат может быть сохранен в переменной, передан и позже может быть вызван:val f = foo() f() //equivalent to f.invoke()
Это также почему
foo()()
в примере выполняется код из лямбда-тела.