Введение: Зачем нужны функции и почему это круто?
Представь, что ты строишь робота. Если бы каждый раз, когда роботу нужно было поднять руку, тебе приходилось заново собирать все шестерёнки и провода — это было бы ужасно долго и неудобно. Вместо этого ты один раз собираешь механизм руки, даёшь ему команду «поднять руку», и робот выполняет её, когда нужно.
В программировании функции работают точно так же. Это такие «мини-программы» внутри твоей основной программы. Ты пишешь код один раз, а потом можешь использовать его снова и снова, просто вызвав функцию по имени.
Представь, что ты пишешь игру. Тебе нужно, чтобы персонаж прыгал каждый раз, когда игрок нажимает пробел. Без функций тебе пришлось бы копировать один и тот же код прыжка в каждое место программы. А если ты захочешь изменить высоту прыжка? Пришлось бы править код в 50 местах! С функциями ты меняешь код только внутри функции, и всё работает везде.
Сегодня мы научимся создавать свои собственные функции, передавать им данные и получать результаты. Это сделает твой код чище, короче и понятнее.
Что такое функция? Простая аналогия
Представь, что функция — это автомат по производству пиццы:
- Ты вход (входные данные): кладёшь тесто, сыр, колбасу
- Автомат выполняет действия (код функции): замешивает, выпекает, нарезает
- Ты получаешь результат (выходные данные): готовую пиццу
Но есть и автоматы, которые ничего не выдают — например, кофейный автомат, который просто греет воду, но ты не забираешь стаканчик. В программировании тоже есть функции без результата.
Синтаксис функции в Kotlin
Вот как выглядит самая простая функция в Kotlin:
fun приветствовать() {
println("Привет, мир!")
}
Разберём по частям:
fun— ключевое слово, которое говорит: «Я создаю функцию»приветствовать— имя функции (придумываешь сам)()— круглые скобки. В них мы будем передавать входные данные. Пока они пустые{ ... }— тело функции. Внутри — код, который выполняется
Чтобы функция заработала, её нужно вызвать:
fun main() {
приветствовать() // Вызов функции
приветствовать() // Можно вызвать сколько угодно раз!
}
Вывод в консоль:
Привет, мир!
Привет, мир!
Функции с параметрами (входные данные)
Помнишь автомат с пиццей? Чтобы он работал, нужно положить ингредиенты. В функции это называются параметры.
Давай напишем функцию, которая приветствует конкретного человека:
fun приветствоватьПользователя(имя: String) {
println("Привет, $имя!")
}
fun main() {
приветствоватьПользователя("Алиса") // Вывод: Привет, Алиса!
приветствоватьПользователя("Боб") // Вывод: Привет, Боб!
}
Здесь имя: String — это параметр. Когда мы вызываем функцию, мы передаём аргумент ("Алиса", "Боб"). Функция подставляет его в текст.
Важно: Параметр — это переменная, которую ты создаёшь внутри функции. Она доступна только внутри функции!
Несколько параметров
Можно передавать сколько угодно параметров, разделяя их запятыми:
fun показатьИнфо(имя: String, возраст: Int) {
println("Меня зовут $имя, мне $возраст лет.")
}
fun main() {
показатьИнфо("Саша", 14) // Вывод: Меня зовут Саша, мне 14 лет.
показатьИнфо("Маша", 12) // Вывод: Меня зовут Маша, мне 12 лет.
}
Функции с возвращаемым значением
Некоторые функции не просто печатают текст, а возвращают результат, который можно сохранить в переменную или использовать дальше.
Пример: функция, которая складывает два числа:
fun сложить(a: Int, b: Int): Int {
return a + b
}
fun main() {
val сумма = сложить(5, 3)
println("Сумма равна $сумма") // Вывод: Сумма равна 8
// Можно использовать результат сразу:
println(сложить(10, 20)) // Вывод: 30
}
Разберём новое:
: Intпосле скобок — это тип возвращаемого значения. Функция обещает вернуть число типа Intreturn— ключевое слово, которое говорит: «Вот результат, забирай!»- После
returnфункция сразу завершается. Код послеreturnне выполняется
Функция, которая проверяет, чётное ли число
fun являетсяЧётным(число: Int): Boolean {
return число % 2 == 0
}
fun main() {
val число = 7
if (являетсяЧётным(число)) {
println("$число — чётное")
} else {
println("$число — нечётное")
}
}
Обрати внимание: число % 2 == 0 — это выражение, которое само возвращает true или false. Мы можем сразу вернуть его без if.
Функции без возвращаемого значения (Unit)
Когда функция ничего не возвращает, Kotlin подразумевает тип Unit. Его можно не писать. Это как сказать: «Я просто делаю что-то, но ничего не отдаю».
fun показатьОшибку(сообщение: String): Unit { // : Unit можно не писать
println("ОШИБКА: $сообщение")
}
Такие функции полезны для вывода, изменения глобальных переменных или работы с файлами.
Реальные примеры: зачем это в жизни?
Давай представим, что ты пишешь программу для школьной столовой. Тебе нужно:
- Посчитать стоимость обеда
- Проверить, хватает ли денег на карте
- Выдать чек
Без функций код превратится в кашу. С функциями — это просто:
fun рассчитатьСтоимость(суп: Double, второе: Double, компот: Double): Double {
return суп + второе + компот
}
fun проверитьБаланс(баланс: Double, стоимость: Double): Boolean {
return баланс >= стоимость
}
fun выдатьЧек(имя: String, сумма: Double) {
println("Чек для $имя")
println("Итого: $сумма руб.")
println("Спасибо за покупку!")
}
fun main() {
val балансАлисы = 150.0
val стоимость = рассчитатьСтоимость(50.0, 80.0, 30.0) // 160.0
if (проверитьБаланс(балансАлисы, стоимость)) {
выдатьЧек("Алиса", стоимость)
} else {
println("Недостаточно средств!")
}
}
Видишь, как чисто? Каждая функция делает только своё дело. Если нужно изменить расчёт стоимости — меняешь только одну функцию.
Параметры по умолчанию
В Kotlin можно задать значения по умолчанию для параметров. Если при вызове их не передать, используется значение по умолчанию.
fun приветствие(имя: String = "Гость") {
println("Добро пожаловать, $имя!")
}
fun main() {
приветствие() // Вывод: Добро пожаловать, Гость!
приветствие("Дима") // Вывод: Добро пожаловать, Дима!
}
Это удобно, когда у функции много параметров, но не все нужны каждый раз.
Именованные аргументы
Когда у функции много параметров, легко запутаться в порядке. Kotlin позволяет передавать аргументы по имени:
fun создатьПрофиль(имя: String, возраст: Int, город: String, хобби: String) {
println("$имя, $возраст лет, из города $город. Любит $хобби.")
}
fun main() {
// Можно в любом порядке!
создатьПрофиль(
хобби = "футбол",
имя = "Петя",
город = "Москва",
возраст = 13
)
}
Это особенно полезно, когда у функции много параметров с одинаковым типом.
Локальные переменные и область видимости
Переменные, созданные внутри функции, видны только внутри неё. Это называется область видимости.
fun тест() {
val секрет = 42
println(секрет) // Всё ок
}
fun main() {
// println(секрет) // ОШИБКА! Переменная секрет не видна здесь
}
Это хорошо: ты можешь использовать одинаковые имена в разных функциях, и они не будут мешать друг другу.
Функции, вызывающие другие функции
Функции могут вызывать другие функции. Это основа модульного программирования — разбиения задачи на маленькие части.
fun получитьПриветствие(имя: String): String {
return "Привет, $имя!"
}
fun показатьПриветствие(имя: String) {
val сообщение = получитьПриветствие(имя)
println(сообщение)
}
fun main() {
показатьПриветствие("Оля") // Вывод: Привет, Оля!
}
Здесь показатьПриветствие вызывает получитьПриветствие и использует её результат. Так можно строить целые цепочки.
Ошибки, которые часто делают новички
- Забывают вызвать функцию — если написать только
приветствоватьбез скобок, код не выполнится. Скобки обязательны! - Путают параметры и аргументы — параметр — это переменная в определении функции, аргумент — конкретное значение при вызове.
- Пишут код после return — он никогда не выполнится. Компилятор даже предупредит об ошибке.
- Не указывают тип возвращаемого значения — если функция должна вернуть число, нужно писать
: Intи т.д.
Когда стоит создавать функцию?
Вот простые правила:
- Если ты копируешь один и тот же код больше двух раз — вынеси его в функцию
- Если кусок кода делает что-то логически законченное (например, считает среднее) — это кандидат на функцию
- Если код сложный — разбей его на несколько маленьких функций с понятными названиями
Хорошее имя функции начинается с глагола: посчитатьПлощадь, найтиМаксимум, проверитьДоступ. Имя должно сразу говорить, что делает функция.
Практические задания
Теперь твоя очередь! Попробуй решить эти задачи самостоятельно. Если что-то не получается — перечитай урок или попроси помощи.
Задание 1: Калькулятор скидок
Напиши функцию посчитатьСкидку, которая принимает цену: Double и процентСкидки: Int (по умолчанию 10). Функция должна вернуть цену со скидкой. В main вызови её дважды: один раз со скидкой 20%, второй раз без указания скидки (чтобы использовалось значение по умолчанию).
Подсказка: цена со скидкой = цена * (100 - процент) / 100
Задание 2: Проверка пароля
Создай функцию проверитьПароль, которая принимает строку пароль: String и возвращает Boolean — true, если пароль длиннее 8 символов и содержит хотя бы одну цифру. Иначе — false.
Подсказки:
- Длина строки:
пароль.length - Проверить, содержит ли цифру:
пароль.any { it.isDigit() }
В main протестируй функцию с разными паролями и выведи результат.
Задание 3: Игровой персонаж
Напиши программу для RPG-игры. Создай функцию атаковать, которая принимает имяАтакующего: String, имяЦели: String и урон: Int. Функция должна выводить сообщение в формате:
Герой {имяАтакующего} наносит {урон} урона монстру {имяЦели}!
Затем создай функцию получитьУрон, которая принимает текущееЗдоровье: Int и урон: Int и возвращает новое значение здоровья (не меньше 0).
В main смоделируй бой: пусть герой атакует монстра, у которого 50 HP, нанося 15 урона. Выведи оставшееся здоровье монстра.
Удачи! Ты справишься!
«Функции — это кирпичики, из которых строится любая программа. Научись их писать хорошо — и ты сможешь написать что угодно.»