Kotlin Bootcamp для программистов 2: основы Kotlin

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

Введение

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

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

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

  • Как создать проект в IntelliJ IDEA
  • Как открыть и выполнить код в Kotlin REPL (цикл чтения-оценки-печати) в IntelliJ IDEA ( Инструменты > Kotlin > Kotlin REPL )

Что вы узнаете

  • Как использовать типы данных, операторы и переменные Kotlin
  • Как работать с логическими значениями и условиями
  • Разница между обнуляемыми и необнуляемыми переменными
  • Как работают массивы, списки и циклы в Kotlin

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

  • Работайте с Kotlin REPL, чтобы изучить основы Kotlin.

В этом задании вы узнаете об операторах и типах языка программирования Kotlin.

Шаг 1. Изучите числовые операторы

  1. Откройте IntelliJ IDEA, если он еще не открыт.
  2. Чтобы открыть Kotlin REPL, выберите Tools > Kotlin > Kotlin REPL .

Как и в других языках, Kotlin использует + , - , * и / для плюса, минуса, времени и деления. Kotlin также поддерживает различные типы чисел, такие как Int , Long , Double и Float .

  1. Введите следующие выражения в REPL. Чтобы увидеть результат, нажимайте Control+Enter ( Command+Enter на Mac) после каждого.
1+1
⇒ res8: kotlin.Int = 2

53-3
⇒ res9: kotlin.Int = 50

50/10
⇒ res10: kotlin.Int = 5

1.0/2.0
⇒ res11: kotlin.Double = 0.5

2.0*3.5
⇒ res12: kotlin.Double = 7.0

Обратите внимание, что результаты операций сохраняют типы операндов, поэтому 1/2 = 0, а 1,0/2,0 = 0,5.

  1. Попробуйте некоторые выражения с различными комбинациями целых и десятичных чисел.
6*50
⇒ res13: kotlin.Int = 300

6.0*50.0
⇒ res14: kotlin.Double = 300.0

6.0*50
⇒ res15: kotlin.Double = 300.0
  1. Вызовите некоторые методы для чисел. Kotlin хранит числа как примитивы, но позволяет вызывать методы для чисел, как если бы они были объектами.
2.times(3)
⇒ res5: kotlin.Int = 6

3.5.plus(4)
⇒ res8: kotlin.Double = 7.5

2.4.div(2)
⇒ res9: kotlin.Double = 1.2

Шаг 2. Попрактикуйтесь в использовании типов

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

  1. Чтобы увидеть некоторые возможные приведения, определите переменную типа Int в REPL.
val i: Int = 6
  1. Создайте новую переменную, затем введите имя переменной, показанное выше, а затем .to .
val b1 = i.to

IntelliJ IDEA отображает список возможных завершений. Это автодополнение работает для переменных и объектов любого типа.

  1. Выберите toByte() из списка, затем напечатайте переменную.
val b1 = i.toByte()
println(b1)
⇒ 6
  1. Присвойте значение Byte переменным разных типов.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1

val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected

val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected

val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
  1. Для заданий, которые вернули ошибки, попробуйте вместо этого привести их.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1

val i5: String = b2.toString()
println(i5)
⇒ 1

val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
  1. Чтобы сделать длинные числовые константы более удобочитаемыми, Kotlin позволяет вам размещать символы подчеркивания в числах там, где это имеет для вас смысл. Попробуйте ввести другие числовые константы.
val oneMillion = 1_000_000
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Шаг 3: Изучите значение типов переменных

Kotlin поддерживает два типа переменных: изменяемые и неизменяемые. С помощью val вы можете присвоить значение один раз. Если вы попытаетесь назначить что-то еще раз, вы получите ошибку. С помощью var вы можете присвоить значение, а затем изменить его позже в программе.

  1. Определите переменные, используя val и var , а затем присвойте им новые значения.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned

Вы можете присвоить fish значение, а затем присвоить ему новое значение, потому что оно определено с помощью var . Попытка присвоить aquarium новое значение приводит к ошибке, потому что оно определено с помощью val .

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

  1. Определите некоторые переменные и явно укажите тип.
var fish: Int = 12
var lakes: Double = 2.5

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

Шаг 4. Узнайте о строках

Строки в Kotlin работают почти так же, как строки в любом другом языке программирования, используя " для строк и ' для отдельных символов, и вы можете объединять строки с помощью оператора + . Вы можете создавать шаблоны строк, комбинируя их со значениями; имя variable $ заменяется с текстом, представляющим значение.Это называется интерполяцией переменных .

  1. Создайте шаблон строки.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
  1. Создайте строковый шаблон с выражением в нем. Как и в других языках, значение может быть результатом выражения. Используйте фигурные скобки {} , чтобы определить выражение.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants

В этом задании вы узнаете о логических значениях и условиях проверки в языке программирования Kotlin. Как и в других языках, в Kotlin есть логические значения и логические операторы, такие как меньше, равно, больше и т. д. ( < , == , > , != , <= , >= ).

  1. Напишите оператор if / else .
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
    println("Good ratio!") 
} else {
    println("Unhealthy ratio")
}
⇒ Good ratio!
  1. Попробуйте диапазон в операторе if . В Kotlin условие, которое вы тестируете, также может использовать диапазоны.
val fish = 50
if (fish in 1..100) {
    println(fish)
}
⇒ 50
  1. Напишите if с несколькими случаями. Для более сложных условий используйте логические и && и логические или || . Как и в других языках, вы можете иметь несколько вариантов, используя else if .
if (numberOfFish == 0) {
    println("Empty tank")
} else if (numberOfFish < 40) {
    println("Got fish!")
} else {
    println("That's a lot of fish!")
}
⇒ That's a lot of fish!
  1. Попробуйте оператор when . Есть более приятный способ написать эту серию операторов if / else if / else в Kotlin, используя оператор when , который похож на оператор switch в других языках. Условия в операторе when также могут использовать диапазоны.
when (numberOfFish) {
    0  -> println("Empty tank")
    in 1..39 -> println("Got fish!")
    else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!

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

Шаг 1. Узнайте о допустимости значений NULL

По умолчанию переменные не могут иметь значение null .

  1. Объявите Int и присвойте ему null .
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
  1. Используйте оператор вопросительного знака, ? , после типа, чтобы указать, что переменная может иметь значение null. Объявить Int? и присвойте ему значение null .
var marbles: Int? = null

Когда у вас есть сложные типы данных, такие как список:

  • Вы можете разрешить элементам списка быть нулевыми.
  • Вы можете разрешить списку быть нулевым, но если он не нулевой, его элементы не могут быть нулевыми.
  • Вы можете разрешить как списку, так и элементам быть нулевыми.

Списки и некоторые другие сложные типы данных рассматриваются в следующей задаче.

Шаг 2: Узнайте о? и ?: операторы

Вы можете проверить значение null с помощью ? оператора, избавляя вас от необходимости писать множество операторов if / else .

  1. Напишите более длинный код, чтобы проверить, не является ли переменная fishFoodTreats null . Затем уменьшите эту переменную.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
    fishFoodTreats = fishFoodTreats.dec()
}
  1. Теперь посмотрите на способ написания Kotlin, используя ? оператор.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
  1. Вы также можете связать нулевые тесты с оператором ?: . Посмотрите на этот пример:
fishFoodTreats = fishFoodTreats?.dec() ?: 0

Это сокращение для «если fishFoodTreats не равно null , уменьшите и используйте его; в противном случае используйте значение после ?: , которое равно 0». Если fishFoodTreats равно null , оценка останавливается и метод dec() не вызывается.

Пункт о нулевых указателях

Если вы действительно любите NullPointerExceptions , Kotlin позволяет вам их сохранить. Оператор ненулевого утверждения !! (двойной удар), преобразует любое значение в ненулевой тип и выдает исключение, если значение равно null .

val len = s!!.length   // throws NullPointerException if s is null

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

Шаг 1: Составьте списки

Списки являются основным типом в Kotlin и похожи на списки в других языках.

  1. Объявите список с помощью listOf и распечатайте его. Этот список нельзя изменить.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
  1. Объявите список, который можно изменить, используя mutableListOf . Удалить элемент.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true

Метод remove() возвращает значение true , когда он успешно удаляет переданный элемент.

Шаг 2: Создайте массивы

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

Правила использования val и var для массивов такие же, как и для списков.

  1. Объявите массив строк с помощью arrayOf . Используйте утилиту массива java.util.Arrays.toString() , чтобы распечатать его.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
  1. Массив, объявленный с помощью arrayOf , не имеет типа, связанного с элементами, поэтому вы можете смешивать типы, что полезно. Объявите массив с разными типами.
val mix = arrayOf("fish", 2)
  1. Вы также можете объявить массивы с одним типом для всех элементов. Объявите массив целых чисел с помощью intArrayOf() . Существуют соответствующие построители или функции создания экземпляров для массивов других типов.
val numbers = intArrayOf(1,2,3)
  1. Объедините два массива с помощью оператора + .
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
  1. Попробуйте разные комбинации вложенных массивов и списков. Как и в других языках, вы можете вкладывать массивы и списки. То есть, когда вы помещаете массив в массив, у вас есть массив массивов, а не сглаженный массив содержимого двух. Элементы массива также могут быть списками, а элементы списков могут быть массивами.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]

Первый элемент, numbers , является Array . Когда вы не используете утилиту массива для его печати, Kotlin печатает адрес вместо содержимого массива.

  1. Одна приятная особенность Kotlin заключается в том, что вы можете инициализировать массивы с помощью кода вместо их инициализации 0. Попробуйте этот пример:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]

Код инициализации находится между фигурными скобками {} . В коде it относится к индексу массива, начиная с 0.

Шаг 3: Сделайте петли

Теперь, когда у вас есть списки и массивы, цикл по элементам работает так, как вы могли ожидать.

  1. Создайте массив. Используйте цикл for для перебора массива и печати элементов.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
    print(element + " ")
}
⇒ shark salmon minnow
  1. В Kotlin вы можете одновременно перебирать элементы и индексы. Попробуйте этот пример:
for ((index, element) in school.withIndex()) {
    println("Item at $index is $element\n")
}
⇒ Item at 0 is shark
Item at 1 is salmon
Item at 2 is minnow
  1. Попробуйте разные размеры и диапазоны шагов. Вы можете указать диапазоны чисел или символов в алфавитном порядке. И, как и в других языках, вам не нужно делать шаг вперед на 1. Вы можете сделать шаг назад, используя downTo .
for (i in 1..5) print(i)
⇒ 12345

for (i in 5 downTo 1) print(i)
⇒ 54321

for (i in 3..6 step 2) print(i)
⇒ 35

for (i in 'd'..'g') print (i)
⇒ defg
  1. Попробуйте несколько циклов. Как и в других языках, в Kotlin есть циклы while , do...while , а также операторы ++ и -- . В Kotlin также есть repeat циклы.
var bubbles = 0
while (bubbles < 50) {
    bubbles++
}
println("$bubbles bubbles in the water\n")

do {
    bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")

repeat(2) {
     println("A fish is swimming")
}
⇒ 50 bubbles in the water
49 bubbles in the water
A fish is swimmingA fish is swimming

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

Следующие функции могут отличаться в Kotlin от того, к чему вы привыкли в других языках:

  • Типы Kotlin не могут быть преобразованы неявно — используйте приведение типов.
  • Переменные, объявленные с помощью val , могут быть назначены только один раз.
  • Переменные Kotlin по умолчанию не имеют значения NULL. Использовать ? чтобы сделать переменные обнуляемыми.
  • С Kotlin вы можете одновременно перебирать индекс и элементы массива в цикле for .

Следующие программные конструкции Kotlin аналогичны конструкциям других языков:

  • Массивы и списки могут иметь один тип или смешанные типы.
  • Массивы и списки могут быть вложенными.
  • Вы можете создавать циклы с for , while , do / while и repeat .
  • Оператор when — это Kotlin-версия оператора switch , но when он более гибкий.

Котлин документация

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

Учебники по Котлину

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

Удасити курс

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

IntelliJ ИДЕЯ

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

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

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

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

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

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

Вопрос 1

Что из следующего объявляет неизменяемый список строк?

val school = arrayOf("shark", "salmon", "minnow")

var school = arrayOf("shark", "salmon", "minnow")

val school = listOf("shark", "salmon", "minnow")

val school = mutableListOf("shark", "salmon", "minnow")

вопрос 2

Каким будет вывод следующего кода?
for (i in 3..8 step 2) print(i)

▢ 345678

▢ 468

▢ 38

▢ 357

Вопрос 3

Какова цель вопросительного знака в этом коде?
var rocks: Int? = 3

▢ Тип переменных rocks не фиксирован.

▢ Переменные rocks можно установить равными нулю.

▢ Переменная rocks не может быть установлена ​​на нуль.

▢ Переменные rocks не должны быть инициализированы сразу.

Перейти к следующему уроку: 3. Функции

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