Spec-Zone.ru › Kotlin 2

Функции

В Kotlin можно объявлять собственные функции с помощью ключевого слова fun.

fun hello() {
    return println("Hello, world!")
}

fun main() {
    hello()
    // Hello, world!
}

В Kotlin:

  • Параметры функции записываются в круглых скобках ().

  • У каждого параметра должен быть указан тип, а несколько параметров необходимо разделять запятыми ,.

  • Тип возвращаемого значения указывается после круглых скобок функции () и отделяется двоеточием :.

  • Тело функции записывается в фигурных скобках {}.

  • Ключевое слово return используется, чтобы выйти из функции или вернуть из неё значение.

Если функция не возвращает полезное значение, тип возвращаемого значения и ключевое слово 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
}

В наших соглашениях о написании кода мы рекомендуем начинать имена функций со строчной буквы и использовать верблюжий регистр без подчёркиваний.

Именованные аргументы

Чтобы код был лаконичным, при вызове функции имена параметров можно не указывать. Однако с именами параметров код легче читать. Такой способ называется использованием именованных аргументов. Если вы указываете имена параметров, их можно записать в любом порядке.

В следующем примере для доступа к значениям параметров, преобразования их в тип String и последующей конкатенации в строку для вывода используются шаблоны строк ($).

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
}

Однако, чтобы другие разработчики могли быстро понять ваш код, рекомендуется явно указывать тип возвращаемого значения, даже если используется оператор присваивания =.

Если для объявления тела функции используются фигурные скобки {}, необходимо указать тип возвращаемого значения, если только это не тип Unit.

Досрочный выход из функции

Чтобы остановить выполнение кода функции на определённом этапе, используйте ключевое слово 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, которая принимает в качестве параметра радиус круга в целочисленном формате и вычисляет площадь этого круга.

В этом упражнении вы импортируете пакет, чтобы получить доступ к значению с помощью PI. Подробнее об импорте пакетов см. в разделе Пакеты и импорты.

Подсказка

Формула для вычисления площади круга: , где — радиус.

import kotlin.math.PI

// Write your code here

fun main() {
    println(circleArea(2))
}
import kotlin.math.PI fun circleArea(radius: Int): Double { return PI * radius * radius } fun main() { println(circleArea(2)) // 12.566370614359172 }

Упражнение 2

Перепишите функцию circleArea из предыдущего упражнения в виде функции с одним выражением.

import kotlin.math.PI

// Write your code here

fun main() {
    println(circleArea(2))
}
import kotlin.math.PI fun circleArea(radius: Int): Double = PI * radius * radius fun main() { println(circleArea(2)) // 12.566370614359172 }

Упражнение 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))
}
fun intervalInSeconds(hours: Int = 0, minutes: Int = 0, seconds: Int = 0) = ((hours * 60) + minutes) * 60 + seconds fun main() { println(intervalInSeconds(1, 20, 15)) println(intervalInSeconds(minutes = 1, seconds = 25)) println(intervalInSeconds(hours = 2)) println(intervalInSeconds(minutes = 10)) println(intervalInSeconds(hours = 1, seconds = 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() выводит результат.

Если вы объявляете лямбда-выражение без параметров, использовать -> не нужно. Например:

{ println("Log message") }

Лямбда-выражения можно использовать разными способами. Вы можете:

  • Передать лямбда-выражение в качестве параметра другой функции

  • Вернуть лямбда-выражение из функции

  • Вызвать лямбда-выражение отдельно

Передача в другую функцию

Отличный пример ситуации, когда полезно передать лямбда-выражение функции, — использование функции .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) в лямбда-выражении.

Если лямбда-выражение — единственный параметр функции, круглые скобки функции () можно опустить:

val positives = numbers.filter { x -> x > 0 }

Это пример лямбда-выражения в конце вызова; подробнее о нём рассказывается в конце этой главы.

Ещё один хороший пример — использование функции .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

Типы параметров и возвращаемого значения необходимо объявить либо в лямбда-выражении, либо в типе функции. Иначе компилятор не сможет определить тип лямбда-выражения.

Например, следующий код не будет работать:

val upperCaseString = { str -> str.uppercase() }

Возврат из функции

Лямбда-выражения можно возвращать из функции. Чтобы компилятор понимал, какой тип имеет возвращаемое лямбда-выражение, необходимо объявить тип функции.

В следующем примере функция 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)
}
fun main() { val actions = listOf("title", "year", "author") val prefix = "https://example.com/book-info" val id = 5 val urls = actions.map { action -> "$prefix/$id/$action" } println(urls) }

Упражнение 2

Напишите функцию, которая принимает значение Int и действие (функцию типа () -> Unit), а затем повторяет действие заданное число раз. Используйте эту функцию, чтобы вывести «Hello» 5 раз.

fun repeatN(n: Int, action: () -> Unit) {
    // Write your code here
}

fun main() {
    // Write your code here
}
fun repeatN(n: Int, action: () -> Unit) { for (i in 1..n) { action() } } fun main() { repeatN(5) { println("Hello") } }
  • Предыдущий этап

  • Следующий этап

12 августа 2026
Управление потоком выполненияКлассы

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API