Однострочные функции (single expression function) используют сокращенный синтаксис определения функции в виде одного выражения. Эта форма позволяет опустить возвращаемый тип и оператор return.
fun имя_функции (параметры_функции) = тело_функции
Функция также определяется с помощью ключевого слова fun, после которого идет имя функции и список параметров. Но после списка параметров не указывается возвращаемый тип. Возвращаемый тип будет выводится компилятором. Далее через оператор присвоения = определяется тело функции в виде одного выражения.
Например, функция возведения числа в квадрат:
fun square(x: Int) = x * x fun main() { val a = square(5) // 25 val b = square(6) // 36 println("a=$a b=$b") }
В данном случае функция square возводит число в квадрат. Она состоит из одного выражения x * x
. Значение этого выражения и будет возвращаться функцией. При этом оператор return не используется.
Такие функции более лаконичны, более читабельны, но также опционально можно и указывать возвращаемый тип явно:
fun square(x: Int) : Int = x * x
Одни функции могут быть определены внутри других функций. Внутренние или вложенные функции еще называют локальными.
Локальные функции могут определять действия, которые используются только в рамках какой-то конкретной функции и нигде больше не применяются.
Например, у нас есть функция, которая сравнивает два возраста:
fun compareAge(age1: Int, age2: Int){ fun ageIsValid(age: Int): Boolean{ return age > 0 && age < 111 } if( !ageIsValid(age1) || !ageIsValid(age2)) { println("Invalid age") return } when { age1 == age2 -> println("age1 == age2") age1 > age2 -> println("age1 > age2") age1 < age2 -> println("age1 < age2") } } fun main() { compareAge(20, 23) compareAge(-3, 20) compareAge(34, 134) compareAge(15, 8) }
Однако извне могут быть переданы некорректные данные. Имеет ли смысл сравнивать возраст меньше нуля с другим? Очевидно нет. Для этой цели в функции
определена локальная функция ageIsValid()
, которая возвращает true, если возраст является допустимым. Больше в программе эта функция нигде не используется, поэтому ее можно сделать локальной.
При этом локальная может использоваться только в той функции, где она определена.
Причем в данном случае удобнее сделать локальную функцию однострочной:
fun compareAge(age1: Int, age2: Int){ fun ageIsValid(age: Int)= age > 0 && age < 111 if( !ageIsValid(age1) || !ageIsValid(age2)) { println("Invalid age") return } when { age1 == age2 -> println("age1 == age2") age1 > age2 -> println("age1 > age2") age1 < age2 -> println("age1 < age2") } }