Kotlin Bootcamp для программистов 3: Функции

Эта практическая работа является частью курса Kotlin Bootcamp for Programmers . Вы получите максимальную пользу от этого курса, если будете выполнять задания последовательно. В зависимости от вашего уровня знаний, вы можете пропустить некоторые разделы. Этот курс ориентирован на программистов, владеющих объектно-ориентированным языком программирования и желающих изучить Kotlin .

Введение

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

Вместо создания одного примера приложения уроки этого курса направлены на углубление ваших знаний, но при этом они частично независимы друг от друга, чтобы вы могли бегло просмотреть знакомые разделы. Чтобы связать их воедино, многие примеры используют тему аквариума. А если вы хотите узнать всё об аквариуме, ознакомьтесь с курсом Kotlin Bootcamp for Programmers на Udacity.

Что вам уже следует знать

  • Основы современного объектно-ориентированного статически типизированного языка программирования
  • Как программировать с использованием классов, методов и обработки исключений хотя бы на одном языке
  • Как работать с REPL (цикл чтения-вычисления-печати) Kotlin в IntelliJ IDEA
  • Основы Kotlin, включая типы, операторы и циклы

Эта лабораторная работа ориентирована на программистов, владеющих объектно-ориентированным языком и желающих узнать больше о Kotlin.

Чему вы научитесь

  • Как создать программу с функцией main() и аргументами в IntelliJ IDEA
  • Как использовать значения по умолчанию и компактные функции
  • Как применять фильтры к спискам
  • Как создавать базовые лямбда-выражения и функции высшего порядка

Что ты будешь делать?

  • Поработайте с REPL, чтобы опробовать какой-нибудь код.
  • Используйте IntelliJ IDEA для создания базовых программ на Kotlin.

В этом задании вы создадите программу на языке Kotlin и узнаете о функции main() , а также о том, как передавать аргументы в программу из командной строки.

Возможно, вы помните функцию printHello() , которую вы ввели в REPL в предыдущей лабораторной работе:

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

Функции определяются с помощью ключевого слова fun , за которым следует имя функции. Как и в других языках программирования, скобки () используются для указания аргументов функции, если таковые имеются. Фигурные скобки {} обрамляют код функции. Для этой функции не задан тип возвращаемого значения, поскольку она ничего не возвращает.

Шаг 1: Создайте файл Kotlin

  1. Откройте IntelliJ IDEA.
  2. На панели «Проект» слева в IntelliJ IDEA отображается список файлов и папок вашего проекта. Найдите и щёлкните правой кнопкой мыши папку src в разделе Hello Kotlin. (У вас уже должен быть проект Hello Kotlin из предыдущей практической работы.)
  3. Выберите Создать > Файл/Класс Kotlin .
  4. Оставьте Kind как File и назовите файл Hello .
  5. Нажмите ОК .

Теперь в папке src есть файл Hello.kt .

Шаг 2: Добавьте код и запустите программу.

  1. Как и в других языках, функция main() в Kotlin определяет точку входа для выполнения. Все аргументы командной строки передаются в виде массива строк.

    Введите или вставьте следующий код в файл Hello.kt :
fun main(args: Array<String>) {
    println("Hello, world!")
}

Как и ваша предыдущая функция printHello() , эта функция не имеет оператора return . Каждая функция в Kotlin что-то возвращает, даже если явно ничего не указано. Поэтому функция, подобная функции main() , возвращает тип kotlin.Unit , что в Kotlin означает отсутствие значения.

  1. Чтобы запустить программу, нажмите на зелёный треугольник слева от функции main() . Выберите в меню пункт «Запустить HelloKt» .
  2. IntelliJ IDEA компилирует программу и запускает её. Результаты отображаются в области журнала внизу, как показано ниже.

Шаг 3: Передайте аргументы в main()

Поскольку вы запускаете свою программу из IntelliJ IDEA, а не из командной строки, вам нужно указывать все аргументы программы немного по-другому.

  1. Выберите «Запуск» > «Изменить конфигурации» . Откроется окно «Конфигурации запуска/отладки» .
  2. В поле «Аргументы программы» введите Kotlin!
  3. Нажмите ОК .

Шаг 4: Измените код, чтобы использовать строковый шаблон.

Строковый шаблон вставляет переменную или выражение в строку, а $ указывает, что часть строки будет переменной или выражением. Фигурные скобки {} заключают выражение в скобки, если оно есть.

  1. В Hello.kt измените приветственное сообщение, чтобы использовать первый аргумент, переданный в программу, args[0] , вместо "world" .
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. Запустите программу, и вывод будет содержать указанный вами аргумент.
⇒ Hello, Kotlin!

В этом задании вы узнаете, почему почти все в Kotlin имеет значение, и почему это полезно.

В некоторых других языках есть операторы (statements) , представляющие собой строки кода без значения. В Kotlin практически всё является выражением и имеет значение, даже если это значение — kotlin.Unit .

  1. В Hello.kt напишите код в main() , чтобы назначить println() переменной isUnit и вывести ее на печать. ( println() не возвращает значение, поэтому он возвращает kotlin.Unit .)
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. Запустите программу. Первый println() выводит строку "This is an expression" . Второй println() выводит значение первого оператора println() , то есть kotlin.Unit .
⇒ This is an expression
kotlin.Unit
  1. Объявите val с именем temperature и инициализируйте его значением 10.
  2. Объявите ещё один val с именем isHot и присвойте isHot возвращаемое значение оператора if / else , как показано в следующем коде. Поскольку это выражение, вы можете сразу использовать значение выражения if .
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. Используйте значение выражения в строковом шаблоне. Добавьте код для проверки температуры, чтобы определить, безопасна ли рыба или слишком тёплая, а затем запустите программу.
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

В этом задании вы узнаете больше о функциях в Kotlin и о весьма полезном условном выражении when .

Шаг 1: Создайте несколько функций

На этом этапе вы объедините полученные знания и создадите функции разных типов. Вы можете заменить содержимое Hello.kt этим новым кодом.

  1. Напишите функцию feedTheFish() , которая вызывает функцию randomDay() для получения случайного дня недели. Используйте строковый шаблон для вывода food , который рыба ест в этот день. Сейчас рыбы едят один и тот же корм каждый день.
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. Напишите функцию randomDay() , которая выбирает случайный день из массива и возвращает его.

Функция nextInt() принимает целочисленный предел, который ограничивает число из Random() диапазоном от 0 до 6, чтобы оно соответствовало массиву week .

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Функции Random() и nextInt() определены в java.util.* . В начале файла добавьте необходимый импорт:
import java.util.*    // required import
  1. Запустите программу и проверьте результат.
⇒ Today is Tuesday and the fish eat pellets

Шаг 2: Используйте выражение when

Расширяя это, измените код так, чтобы он выбирал разные продукты для разных дней, используя выражение when . Оператор when похож на switch в других языках программирования, но when автоматически прерывает выполнение в конце каждой ветви. Это также гарантирует, что ваш код охватывает все ветви, если вы проверяете перечисление.

  1. В Hello.kt добавьте функцию fishFood() , которая принимает номер дня как String и возвращает количество корма, которое рыба получала в этот день, как String . Используйте функцию when() , чтобы каждый день рыба получала определённый корм. Запустите программу несколько раз, чтобы увидеть разные результаты.
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. Добавьте ветку по умолчанию к выражению when с помощью else . Для тестирования, чтобы убедиться, что в вашей программе иногда используется ветка по умолчанию, удалите ветки Tuesday и Saturday .

    Наличие ветви по умолчанию гарантирует, что food получит значение перед возвратом, поэтому его больше не нужно инициализировать. Поскольку код теперь присваивает строку food только один раз, вы можете объявить food с помощью val вместо var .
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. Поскольку каждое выражение имеет значение, вы можете сделать этот код немного короче. Верните значение выражения when напрямую и удалите переменную food . Значение выражения when — это значение последнего выражения ветви, удовлетворяющего условию.
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

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

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

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

Шаг 1: Создайте значение по умолчанию для параметра

В Kotlin можно передавать аргументы по имени параметра. Также можно указать значения параметров по умолчанию: если аргумент не предоставлен вызывающей стороной, используется значение по умолчанию. В дальнейшем, при написании методов (функций-членов), это позволяет избежать написания множества перегруженных версий одного и того же метода.

  1. В Hello.kt напишите функцию swim() со String параметром speed , которая выводит скорость рыбы. Параметр speed имеет значение по умолчанию "fast" .
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. Из функции main() можно вызвать функцию swim() тремя способами. Сначала вызовите функцию, используя значение по умолчанию. Затем вызовите функцию, передав параметр speed без имени, а затем вызовите функцию, указав параметр speed .
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

Шаг 2: Добавьте необходимые параметры

Если для параметра не указано значение по умолчанию, всегда необходимо передавать соответствующий аргумент.

  1. В Hello.kt напишите функцию shouldChangeWater() , которая принимает три параметра: day , temperature и уровень dirty . Функция возвращает true , если воду необходимо сменить, например, в воскресенье, если температура слишком высокая или если вода слишком грязная. Необходимо указать день недели, но температура по умолчанию — 22, а уровень загрязнения — 20.

    Используйте выражение when без аргумента, которое в Kotlin действует как серия проверок if/else if .
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. Вызовите метод shouldChangeWater() из feedTheFish() и укажите день. Параметр day не имеет значения по умолчанию, поэтому необходимо указать аргумент. Два других параметра метода shouldChangeWater() имеют значения по умолчанию, поэтому передавать для них аргументы не нужно.
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

Шаг 3: Создание компактных функций

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

Компактные функции, или функции с одним выражением , — распространённый шаблон в Kotlin. Когда функция возвращает результаты одного выражения, можно указать тело функции после символа = , опустить фигурные скобки {} и опустить return .

  1. в Hello.kt добавьте компактные функции для проверки условий.
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. Измените shouldChangeWater() для вызова новых функций.
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. Запустите программу. Вывод функции println() с shouldChangeWater() должен быть таким же, как и до перехода на компактные функции.

Значения по умолчанию

Значение по умолчанию для параметра не обязательно должно быть значением. Это может быть другая функция, как показано в следующем фрагменте примера:

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

В этом задании вы немного познакомитесь с фильтрами в Kotlin. Фильтры — это удобный способ получить часть списка по определённому условию.

Шаг 1: Создайте фильтр

  1. В Hello.kt определите список аквариумных украшений на верхнем уровне с помощью listOf() . Вы можете заменить содержимое Hello.kt .
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. Создайте новую функцию main() со строкой для вывода только украшений, начинающихся с буквы «p». Код условия фильтра заключен в фигурные скобки {} и it на каждый элемент в цикле фильтра. Если выражение возвращает true , элемент включается в выборку.
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. Запустите программу, и в окне «Выполнить» вы увидите следующий вывод:
⇒ [pagoda, plastic plant]

Шаг 2: Сравните энергичные и ленивые фильтры

Если вы знакомы с фильтрами в других языках, вы можете задаться вопросом, являются ли фильтры в Kotlin жадными (eagy) или ленивыми (lazy) . Создаётся ли список результатов сразу или при обращении к нему? В Kotlin это происходит в зависимости от того, как вам нужно. По умолчанию filter является жадным (eagy), и при каждом его использовании создаётся список.

Чтобы сделать фильтр ленивым, можно использовать Sequence — коллекцию, которая может просматривать только один элемент за раз, начиная с начала и до конца. Удобно, что это именно тот API, который нужен ленивому фильтру.

  1. В Hello.kt измените код так, чтобы отфильтрованный список был назначен переменной с именем eager , а затем выведите его на печать.
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. Ниже этого кода оцените фильтр, используя Sequence с помощью asSequence() . Присвойте последовательность переменной filtered и выведите её на экран.
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

Когда вы возвращаете результаты фильтрации в виде Sequence , filtered переменная не будет содержать новый список — она будет содержать Sequence элементов списка и информацию о фильтре, который нужно применить к этим элементам. При каждом доступе к элементам Sequence , фильтр применяется, и результат возвращается вам.

  1. Принудительно вычислите последовательность, преобразовав её в List с помощью toList() . Выведите результат.
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. Запустите программу и посмотрите на результат.
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Чтобы визуализировать происходящее с Sequence и ленивыми вычислениями, используйте функцию map() . Функция map() выполняет простое преобразование каждого элемента последовательности.

  1. Используя тот же список decorations , что и выше, создайте преобразование с помощью map() , которое ничего не делает и просто возвращает переданный элемент. Добавьте println() для отображения каждого обращения к элементу и присвойте последовательность переменной lazyMap .
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. Выведите lazyMap , выведите первый элемент lazyMap с помощью first() и выведите lazyMap преобразованный в List .
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. Запустите программу и посмотрите на результат. Вывод lazyMap просто выводит ссылку на Sequence — внутренний println() не вызывается. Вывод первого элемента обращается только к первому элементу. Преобразование Sequence в List обращается ко всем элементам.
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. Создайте новую Sequence , используя исходный фильтр перед применением map . Выведите результат на печать.
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. Запустите программу и посмотрите на дополнительный вывод. Как и при получении первого элемента, внутренний println() вызывается только для тех элементов, к которым осуществляется доступ.
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

В этом задании вы получите введение в лямбда-выражения и функции высшего порядка в Kotlin.

Лямбды

Помимо традиционных именованных функций, Kotlin поддерживает лямбда-выражения. Лямбда-выражение — это выражение, создающее функцию. Но вместо объявления именованной функции вы объявляете функцию без имени. Одним из преимуществ этого подхода является то, что лямбда-выражение теперь можно передавать как данные. В других языках программирования лямбда-выражения называются анонимными функциями , функциональными литералами или другими подобными именами.

Функции высшего порядка

Вы можете создать функцию высшего порядка, передав лямбда-выражение другой функции. В предыдущем задании вы создали функцию высшего порядка с именем filter . В качестве условия проверки вы передали следующее лямбда-выражение функции filter :
{it[0] == 'p'}

Аналогично, map — это функция высшего порядка, а переданная ей лямбда — это преобразование, которое нужно применить.

Шаг 1: Узнайте о лямбдах

  1. Как и именованные функции, лямбда-выражения могут иметь параметры. В лямбда-выражениях параметры (и их типы, если необходимо) указываются слева от так называемой стрелки функции -> . Выполняемый код указывается справа от стрелки функции. После присвоения лямбда-выражения переменной его можно вызывать так же, как функцию.

    Используя REPL ( Инструменты > Kotlin > Kotlin REPL ), попробуйте следующий код:
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

В этом примере лямбда-функция принимает Int с именем dirty и возвращает dirty / 2 . (Поскольку фильтрация удаляет dirt.)

  1. Синтаксис Kotlin для типов функций тесно связан с синтаксисом лямбда-выражений. Используйте этот синтаксис для корректного объявления переменной, содержащей функцию:
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

Вот что говорится в коде:

  • Создайте переменную с именем waterFilter .
  • waterFilter может быть любой функцией, которая принимает Int и возвращает Int .
  • Назначьте лямбда-функцию waterFilter .
  • Лямбда возвращает значение аргумента dirty деленное на 2.

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

Шаг 2: Создайте функцию высшего порядка

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

  1. Напишите функцию высшего порядка. Вот простой пример: функция, принимающая два аргумента. Первый аргумент — целое число. Второй аргумент — функция, принимающая целое число и возвращающая целое число. Попробуйте в REPL.
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

Тело кода вызывает функцию, переданную в качестве второго аргумента, и передает ей первый аргумент.

  1. Чтобы вызвать эту функцию, передайте ей целое число и функцию.
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

Передаваемая функция не обязательно должна быть лямбда-функцией; это может быть обычная именованная функция. Чтобы указать аргумент как обычную функцию, используйте оператор :: . Таким образом, Kotlin понимает, что вы передаёте ссылку на функцию как аргумент, а не пытаетесь вызвать её.

  1. Попробуйте передать обычную именованную функцию в updateDirty() .
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • Чтобы создать исходный файл Kotlin в IntelliJ IDEA, начните с проекта Kotlin.
  • Чтобы скомпилировать и запустить программу в IntelliJ IDEA, нажмите на зелёный треугольник рядом с функцией main() . Вывод отобразится в окне журнала ниже.
  • В IntelliJ IDEA укажите аргументы командной строки для передачи в функцию main() в меню Выполнить > Изменить конфигурации .
  • Почти всё в Kotlin имеет значение. Вы можете использовать этот факт, чтобы сделать код более лаконичным, используя значение if или when в качестве выражения или возвращаемого значения.
  • Аргументы по умолчанию устраняют необходимость в нескольких версиях функции или метода. Например:
    fun swim(speed: String = "fast") { ... }
  • Компактные функции, или функции с одним выражением, могут сделать ваш код более читабельным. Например:
    fun isTooHot(temperature: Int) = temperature > 30
  • Вы узнали основы работы с фильтрами, использующими лямбда-выражения. Например:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • Лямбда-выражение — это выражение, создающее безымянную функцию. Лямбда-выражения определяются в фигурных скобках {} .
  • В функции высшего порядка вы передаёте функцию, например лямбда-выражение, другой функции в качестве данных. Например:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

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

Документация Kotlin

Если вам нужна дополнительная информация по какой-либо теме этого курса или вы застряли, лучшей отправной точкой будет https://kotlinlang.org .

Учебники по Kotlin

На сайте https://try.kotlinlang.org вы найдете подробные учебные пособия по Kotlin Koans, веб-интерпретатор и полный набор справочной документации с примерами.

Курс Udacity

Чтобы просмотреть курс Udacity по этой теме, см. Kotlin Bootcamp for Programmers .

IntelliJ IDEA

Документацию по IntelliJ IDEA можно найти на сайте JetBrains.

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

  • При необходимости задавайте домашнее задание.
  • Объясните учащимся, как следует сдавать домашние задания.
  • Оцените домашние задания.

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

Если вы работаете с этой лабораторной работой самостоятельно, можете использовать эти домашние задания для проверки своих знаний.

Ответьте на эти вопросы

Вопрос 1

Функция contains(element: String) возвращает true если element строки содержится в строке, к которой она вызвана. Что будет выведено следующим кодом?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

Вопрос 2

Какой из параметров является обязательным в следующем определении функции?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

Вопрос 3

Вы можете передать обычную именованную функцию (а не результат её вызова) другой функции. Как передать increaseDirty( start: Int ) = start + 1 в updateDirty(dirty: Int, operation: (Int) -> Int) ?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

Перейти к следующему уроку: 4. Классы и объекты

Обзор курса, включая ссылки на другие практические занятия, см. в статье «Kotlin Bootcamp for Programmers: Welcome to the course».