Функции
В Kotlin можно объявлять собственные функции с помощью ключевого слова fun.
fun hello() {
return println("Hello, world!")
}
fun main() {
hello()
// Hello, world!
}
В Kotlin:
Параметры функции записываются в круглых скобках
().У каждого параметра должен быть указан тип, а несколько параметров необходимо разделять запятыми
,.Тип возвращаемого значения указывается после круглых скобок функции
()и отделяется двоеточием:.Тело функции записывается в фигурных скобках
{}.Ключевое слово
returnиспользуется, чтобы выйти из функции или вернуть из неё значение.
В следующем примере:
xиy— параметры функции.Тип параметров
xиy—Int.Тип возвращаемого значения функции —
Int.При вызове функция возвращает сумму
xиy.
fun sum(x: Int, y: Int): Int {
return x + y
}
fun main() {
println(sum(1, 2))
// 3
}
Именованные аргументы
Чтобы код был лаконичным, при вызове функции имена параметров можно не указывать. Однако с именами параметров код легче читать. Такой способ называется использованием именованных аргументов. Если вы указываете имена параметров, их можно записать в любом порядке.
fun printMessageWithPrefix(message: String, prefix: String) {
println("[$prefix] $message")
}
fun main() {
// Uses named arguments with swapped parameter order
printMessageWithPrefix(prefix = "Log", message = "Hello")
// [Log] Hello
}
Значения параметров по умолчанию
Для параметров функции можно задать значения по умолчанию. При вызове функции параметры со значениями по умолчанию можно опустить. Чтобы объявить значение по умолчанию, используйте оператор присваивания = после типа:
fun printMessageWithPrefix(message: String, prefix: String = "Info") {
println("[$prefix] $message")
}
fun main() {
// Function called with both parameters
printMessageWithPrefix("Hello", "Log")
// [Log] Hello
// Function called only with message parameter
printMessageWithPrefix("Hello")
// [Info] Hello
printMessageWithPrefix(prefix = "Log", message = "Hello")
// [Log] Hello
}
Функции без возвращаемого значения
Если функция не возвращает полезное значение, её тип возвращаемого значения — Unit. Unit — это тип, имеющий только одно значение: Unit. Не нужно явно указывать в теле функции, что возвращается Unit. Это значит, что ключевое слово return и тип возвращаемого значения можно не указывать:
fun printMessage(message: String) {
println(message)
// `return Unit` or `return` is optional
}
fun main() {
printMessage("Hello")
// Hello
}
Функции с одним выражением
Чтобы сделать код лаконичнее, можно использовать функции с одним выражением. Например, функцию sum() можно сократить:
fun sum(x: Int, y: Int): Int {
return x + y
}
fun main() {
println(sum(1, 2))
// 3
}
Можно убрать фигурные скобки {} и объявить тело функции с помощью оператора присваивания =. При использовании оператора присваивания = Kotlin выводит тип автоматически, поэтому тип возвращаемого значения тоже можно опустить. Тогда функция sum() будет записана в одну строку:
fun sum(x: Int, y: Int) = x + y
fun main() {
println(sum(1, 2))
// 3
}
Однако, чтобы другие разработчики могли быстро понять ваш код, рекомендуется явно указывать тип возвращаемого значения, даже если используется оператор присваивания =.
Досрочный выход из функции
Чтобы остановить выполнение кода функции на определённом этапе, используйте ключевое слово return. В этом примере if используется для досрочного выхода из функции, если условное выражение истинно:
// A list of registered usernames
val registeredUsernames = mutableListOf("john_doe", "jane_smith")
// A list of registered emails
val registeredEmails = mutableListOf("john@example.com", "jane@example.com")
fun registerUser(username: String, email: String): String {
// Early return if the username is already taken
if (username in registeredUsernames) {
return "Username already taken. Please choose a different username."
}
// Early return if the email is already registered
if (email in registeredEmails) {
return "Email already registered. Please use a different email."
}
// Proceed with the registration if the username and email are not taken
registeredUsernames.add(username)
registeredEmails.add(email)
return "User registered successfully: $username"
}
fun main() {
println(registerUser("john_doe", "newjohn@example.com"))
// Username already taken. Please choose a different username.
println(registerUser("new_user", "newuser@example.com"))
// User registered successfully: new_user
}
Практика: функции
Упражнение 1
Напишите функцию с именем circleArea, которая принимает в качестве параметра радиус круга в целочисленном формате и вычисляет площадь этого круга.
- Подсказка
Формула для вычисления площади круга:
, где — радиус.
import kotlin.math.PI
// Write your code here
fun main() {
println(circleArea(2))
}
Упражнение 2
Перепишите функцию circleArea из предыдущего упражнения в виде функции с одним выражением.
import kotlin.math.PI
// Write your code here
fun main() {
println(circleArea(2))
}
Упражнение 3
У вас есть функция, которая преобразует заданный в часах, минутах и секундах временной интервал в секунды. В большинстве случаев нужно передать только один или два параметра функции, а остальные равны 0. Улучшите функцию и код её вызова, используя значения параметров по умолчанию и именованные аргументы, чтобы код было легче читать.
fun intervalInSeconds(hours: Int, minutes: Int, seconds: Int) =
((hours * 60) + minutes) * 60 + seconds
fun main() {
println(intervalInSeconds(1, 20, 15))
println(intervalInSeconds(0, 1, 25))
println(intervalInSeconds(2, 0, 0))
println(intervalInSeconds(0, 10, 0))
println(intervalInSeconds(1, 0, 1))
}
Лямбда-выражения
В Kotlin можно писать ещё более лаконичный код для функций, используя лямбда-выражения.
Например, следующую функцию uppercaseString():
fun uppercaseString(text: String): String {
return text.uppercase()
}
fun main() {
println(uppercaseString("hello"))
// HELLO
}
можно также записать в виде лямбда-выражения:
fun main() {
val upperCaseString = { text: String -> text.uppercase() }
println(upperCaseString("hello"))
// HELLO
}
На первый взгляд лямбда-выражения могут показаться сложными, поэтому разберём их подробнее. Лямбда-выражения записываются в фигурных скобках {}.
Внутри лямбда-выражения указываются:
Параметры, за которыми следует
->.Тело функции после
->.
В предыдущем примере:
text— параметр функции.Тип
text—String.Функция возвращает результат вызова функции
.uppercase()дляtext.Всё лямбда-выражение присваивается переменной
upperCaseStringс помощью оператора присваивания=.Лямбда-выражение вызывается с помощью переменной
upperCaseString, как функции, и строки"hello"в качестве параметра.Функция
println()выводит результат.
Лямбда-выражения можно использовать разными способами. Вы можете:
Передача в другую функцию
Отличный пример ситуации, когда полезно передать лямбда-выражение функции, — использование функции .filter() для коллекций:
fun main() {
//sampleStart
val numbers = listOf(1, -2, 3, -4, 5, -6)
val positives = numbers.filter ({ x -> x > 0 })
val isNegative = { x: Int -> x < 0 }
val negatives = numbers.filter(isNegative)
println(positives)
// [1, 3, 5]
println(negatives)
// [-2, -4, -6]
//sampleEnd
}
Функция .filter() принимает лямбда-выражение в качестве предиката и применяет его к каждому элементу списка. Функция оставляет элемент, только если предикат возвращает true:
{ x -> x > 0 }возвращаетtrue, если элемент положительный.{ x -> x < 0 }возвращаетtrue, если элемент отрицательный.
В этом примере показаны два способа передачи лямбда-выражения функции:
Для положительных чисел лямбда-выражение добавляется непосредственно в функцию
.filter().Для отрицательных чисел лямбда-выражение присваивается переменной
isNegative. Затем переменнаяisNegativeиспользуется в качестве параметра функции.filter(). В этом случае необходимо указать тип параметров функции (x) в лямбда-выражении.
Ещё один хороший пример — использование функции .map() для преобразования элементов коллекции:
fun main() {
//sampleStart
val numbers = listOf(1, -2, 3, -4, 5, -6)
val doubled = numbers.map { x -> x * 2 }
val isTripled = { x: Int -> x * 3 }
val tripled = numbers.map(isTripled)
println(doubled)
// [2, -4, 6, -8, 10, -12]
println(tripled)
// [3, -6, 9, -12, 15, -18]
//sampleEnd
}
Функция .map() принимает лямбда-выражение в качестве функции преобразования:
{ x -> x * 2 }получает каждый элемент списка и возвращает его значение, умноженное на 2.{ x -> x * 3 }получает каждый элемент списка и возвращает его значение, умноженное на 3.
Типы функций
Прежде чем возвращать лямбда-выражение из функции, необходимо разобраться с типами функций.
Вы уже познакомились с основными типами, но тип есть и у самих функций. Механизм вывода типов Kotlin может вывести тип функции по типу параметра. Однако иногда тип функции необходимо указать явно. Компилятору нужен тип функции, чтобы определить, что для этой функции допустимо, а что нет.
Синтаксис типа функции включает:
Тип каждого параметра, указанный в круглых скобках
()и отделённый запятыми,.Тип возвращаемого значения, указанный после
->.
Например: (String) -> String или (Int, Int) -> Int.
Вот как выглядит лямбда-выражение, если для upperCaseString() задан тип функции:
val upperCaseString: (String) -> String = { text -> text.uppercase() }
fun main() {
println(upperCaseString("hello"))
// HELLO
}
Если у лямбда-выражения нет параметров, круглые скобки () оставляют пустыми. Например: () -> Unit
Возврат из функции
Лямбда-выражения можно возвращать из функции. Чтобы компилятор понимал, какой тип имеет возвращаемое лямбда-выражение, необходимо объявить тип функции.
В следующем примере функция toSeconds() имеет тип функции (Int) -> Int, поскольку всегда возвращает лямбда-выражение, которое принимает параметр типа Int и возвращает значение типа Int.
В этом примере выражение when определяет, какое лямбда-выражение возвращается при вызове toSeconds():
fun toSeconds(time: String): (Int) -> Int = when (time) {
"hour" -> { value -> value * 60 * 60 }
"minute" -> { value -> value * 60 }
"second" -> { value -> value }
else -> { value -> value }
}
fun main() {
val timesInMinutes = listOf(2, 10, 15, 1)
val min2sec = toSeconds("minute")
val totalTimeInSeconds = timesInMinutes.map(min2sec).sum()
println("Total time is $totalTimeInSeconds secs")
// Total time is 1680 secs
}
Отдельный вызов
Лямбда-выражения можно вызывать отдельно, добавив круглые скобки () после фигурных скобок {} и поместив любые параметры в круглые скобки:
fun main() {
//sampleStart
println({ text: String -> text.uppercase() }("hello"))
// HELLO
//sampleEnd
}
Лямбда-выражения в конце вызова
Как уже было показано, если лямбда-выражение — единственный параметр функции, круглые скобки функции () можно опустить. Если лямбда-выражение передаётся в качестве последнего параметра функции, его можно записать за пределами круглых скобок функции (). В обоих случаях такой синтаксис называется лямбда-выражением в конце вызова.
Например, функция .fold() принимает начальное значение и операцию:
fun main() {
//sampleStart
// The initial value is zero.
// The operation sums the initial value with every item in the list cumulatively.
println(listOf(1, 2, 3).fold(0, { x, item -> x + item })) // 6
// Alternatively, in the form of a trailing lambda
println(listOf(1, 2, 3).fold(0) { x, item -> x + item }) // 6
//sampleEnd
}
Подробнее о лямбда-выражениях см. в разделе Лямбда-выражения и анонимные функции.
Следующий этап нашего знакомства с Kotlin — изучение классов.
Практика: лямбда-выражения
Упражнение 1
У вас есть список действий, поддерживаемых веб-службой, общий префикс для всех запросов и идентификатор определённого ресурса. Чтобы запросить действие title для ресурса с идентификатором 5, нужно создать следующий URL-адрес: https://example.com/book-info/5/title. Используйте лямбда-выражение, чтобы создать список URL-адресов из списка действий.
fun main() {
val actions = listOf("title", "year", "author")
val prefix = "https://example.com/book-info"
val id = 5
val urls = // Write your code here
println(urls)
}
Упражнение 2
Напишите функцию, которая принимает значение Int и действие (функцию типа () -> Unit), а затем повторяет действие заданное число раз. Используйте эту функцию, чтобы вывести «Hello» 5 раз.
fun repeatN(n: Int, action: () -> Unit) {
// Write your code here
}
fun main() {
// Write your code here
}
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/kotlin-tour-functions.html