Учебник по Kotlin: Первые шаги с новым языком программирования

Версия 1.0 стала доступна только в 2016 году, но она уже получила высокую оценку: Kotlin — альтернатива Java. Этот объектно-ориентированный язык программирования разработан чешской компанией JetBrains, специализирующейся на разработке программного обеспечения. Он набирает очки благодаря своему тонкому характеру и тому, что не так часто выдает ошибки во время выполнения — особенно не страшные NullPointerExceptions. Kotlin особенно популярен при разработке приложений для Android. Но и в качестве отправной точки для приложений на JavaScript молодой язык программирования пользуется огромной популярностью.

Kotlin тесно основан на Java: Хотя эти два языка программирования несовместимы, Kotlin преобразуется в байткод, который может быть прочитан виртуальной машиной Java (JVM).

Инструкция по работе с Kotlin — с примерами

Для того чтобы начать работу с Kotlin, вы можете скачать компилятор с официального сайта. С интегрированной средой разработки (IDE) все еще проще: IntelliJ IDEA (также от JetBrains), Eclipse (с соответствующим плагином), NetBeans и Android Studio, например, работают с Kotlin.

Совет

У производителей Kotlin есть онлайн-площадка, где вы можете попробовать все примеры.

Пакеты

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

package test.bar
import foo.bar
import footoo.bar as footoo

Чтобы избежать проблем с одинаковыми именами, в Kotlin можно переименовывать пакеты с помощью «as». Именование пакетов не обязательно должно соответствовать структуре каталогов, в которых они могут быть найдены. Однако для большей ясности рекомендуется использовать эту процедуру.

Примечание

Kotlin автоматически загружает наиболее важные пакеты в каждый проект.

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

import foo.bar.myFunction

После этого функцию можно использовать в обычном режиме.

Совет

В Kotlin строки кода не обязательно завершать метками — например, точкой с запятой.

Переменные

Kotlin знает два различных типа переменных: Те, которые могут быть только прочитаны, фиксированы и помечены как «val». Другие, значение которых может быть изменено в ходе выполнения программы, обозначаются как «var».

val name = "Clara Oswald"
var age = 22

В отличие от фиксированного имени, var можно изменять, например, в функции.

Примечание

В этом примере Kotlin установил тип значения самой переменной. Также можно специально пометить эти базовые типы.

Базовые типы

Kotlin работает с определенными типами для переменных и классов. Каждый тип представляет собой объект, и в этом Kotlin несколько отличается от Java. Если в более старом языке программирования примитивные типы сначала нужно упаковать в обертку, чтобы они вели себя как объекты, то в Kotlin этого не требуется. Здесь все типы уже являются объектами.

Числа

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

  • Long: 64 бита
  • Int: 32 бита
  • Short: 16 бит
  • Байт: 8 бит
  • Двойка: 64 бита
  • Float: 32 бита

Double и float — это числа с плавающей точкой, которые в сложных вычислениях ведут себя иначе, чем числа с фиксированной точкой. Как и все типы, числа можно точно обозначать в коде.

val myNumber: Long = 40

Можно преобразовать число одного типа в другой.

val myInt = 600
val myLong= myInt.toLong()

Команда «toLong» преобразует значение «Int» в значение «Long». Команда работает аналогично для других типов чисел.

Строка

Строка — это слово или целое предложение, то есть строка символов. Чтобы использовать их в Kotlin, поместите написанный текст в двойные кавычки. Если вы хотите вставить несколько строк текста, необходимо поставить три двойные кавычки в начале и в конце (необработанная строка).

val myString = "This is a one-line string."
val myLongString = """This is a string,
that spans several lines."""

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

  • t: Tab
  • b: Backspace
  • n: Новая строка
  • r: Возврат каретки
  • ‘: Одинарная кавычка
  • «»: Двойная кавычка
  • : Обратная косая черта
  • $: Знак доллара

Знак доллара используется в строках для вставки заполнителей. Они могут быть заданы в качестве переменных на предыдущем этапе. Затем заполнитель заменяется в выводе фактическим значением.

val author = "Sandra"
val myString = "This text is from $author"

Символы

Для отдельных символов в Kotlin, помимо строк, предусмотрен специальный тип данных «символ». Однако вместо того, чтобы помещать их в двойные кавычки, используются одинарные кавычки.

var model = 'A'

Булево

Базовый тип «boolean» возвращает истинностное значение, которое может быть либо истинным, либо ложным.

Массивы

В Kotlin массив — это коллекция данных. Вы формируете массив с помощью «arrayOf()» или «Array()». Первая функция проста:

val myArray1 = arrayOf(0, 1, 2, 3, 4, 5)

Она создает массив чисел от 1 до 5, но эти коллекции могут содержать и другие типы, такие как строки и булевы — даже смешанные. Если вы хотите ограничить массив одним типом, укажите это в функции.

val myArray2 = arrayOf(10, 20, 30)
val myArray3 = booleanArrayOf(true, true, false)

Конструктор Kotlin «Array()» сложнее: здесь также нужно указать длину и лямбда-функцию.

val myArray4 = Array(6, { i -> i })

Конструктор создает массив с шестью разрядами и начинает с нуля: 0, 1, 2, 3, 4, 5.

Примечание

Подробнее о конструкторах и лямбдах можно прочитать ниже.

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

fun main() {
	val myArray5 = arrayOf("Jan", "Maria", "Samuel")
	println(myArray5[2])
}
Примечание

В данном случае функция выведет «Samuel», так как счет начинается с 0.

Операторы

Как вы можете знать из многих других языков программирования, Kotlin также работает с различными операторами, которые вы можете интегрировать в свой исходный код. К ним относятся математические операторы (+, -, *, /, %), операторы сравнения (<, >, <=, >=, ==, !=) и логические операторы (&&, ||, !). Так называемые ключевые слова тесно связаны с операторами: это термины, которые имеют фиксированное значение в Kotlin и не могут быть переосмыслены.

Совет

Полный список всех ключевых слов и операторов можно найти в официальной документации Kotlin.

Диапазоны

В Kotlin диапазон описывает тип, который простирается от определенной точки до другой. Чтобы создать диапазон, используйте оператор «.» или функции «rangeTo()» или «downTo()». Вариант с двумя точками, расположенными одна за другой, может отсчитываться вверх. С помощью этих двух функций вы определяете, в какую сторону.

 

val range1 = 1..5
val range2 = 1.rangeTo(5)
val range3 = 5.downTo(1)

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

val range4 = 0..10 step(2)

Чтобы обратиться к отдельным данным в диапазоне, используйте оператор «in». Например, можно создать запрос или цикл. Чтобы проверить, не входит ли значение в диапазон, используйте оператор «!in».

val range5 = 0..10
fun main() {
  for (n in range5) {
    println(n)
  }
  if (7 in range5) {
    println("yes")
  }
  if (12 !in range5) {
    println("no")
  }
}
Примечание

Подробнее о функциях, циклах и запросах см. ниже.

Функции

Функции Kotlin всегда создаются с помощью команды «fun». Затем вы определяете имя функции, аргументы, которые она содержит, и, наконец, то, что она делает.

fun div(a: Int, b: Int): Int {
  return a/b
}
fun main() {
  println(div(100, 2))
}

Сначала мы определяем функцию «div» (для деления) с двумя параметрами Int: a и b. Функция должна выдать нам результат деления a на b, также в виде переменной Int. Наконец, в функции «main» мы обращаемся к ранее определенной функции, передаем ее конкретные значения и выводим результат с помощью «println» (печать строки) в консоль. Kotlin выполняет содержимое «main()» автоматически. Эта функция представляет собой точку входа в программу Kotlin.

Факт

Kotlin не принимает команды, отличные от функций. Разрешены только декларации.

В Kotlin функции, содержащие всего одну строку кода, могут быть упрощены. Вместо того чтобы открывать фигурные скобки, писать новую, вставляемую строку и снова закрывать скобки, используется знак равенства. Команда «return» также опускается.

fun div(a: Int, b: Int): Int = a/b
fun main() = println(div(100, 2))

Чтобы избежать ошибок из-за отсутствия параметров, при определении функции можно указать значения по умолчанию. Если при обращении к функции соответствующие параметры остаются пустыми, используются значения по умолчанию.

fun div(a: Int = 10, b: Int = 5): Int = a/b
fun main() = println(div())

Лямбда

Лямбда-функция (или анонимная функция) — это функция, которая не принадлежит ни классу, ни объекту. Лямбды помещаются непосредственно в другие функции или переменные. Вы можете обращаться к ним без использования ключевого слова «fun». В принципе, лямбды могут использоваться подобно переменным типа «val» и генерируются таким же образом.

fun main() {
  val myMessage = { println("Hello world!") }
  myMessage()
}

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

fun main() {
    val div = {a: Int, b: Int -> a/b}
    println(div(6,2))
}

Классы

Как и в Java, классы в Kotlin представляют собой коллекции данных и функций. Чтобы определить класс, просто вставьте ключевое слово «class». Затем вы можете наполнить новый класс информацией.

class Tardis {
  var year: Int
  var place: String

  constructor(year: Int, place: String) {
    this.year = year
    this.place = place
  }
}

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

Но есть также возможность опустить вторичный конструктор и использовать вместо него первичный конструктор. Вы пишете это прямо в строке заголовка класса и также указываете параметры класса. Это значительно сокращает количество строк кода.

class Tardis constructor(var year: Int, var place: String)

Если вы не хотите предоставлять дополнительную информацию о видимости класса (public, private, protected), вы также можете вообще опустить ключевое слово.

class Tardis (var year: Int, var place: String)

Все три примера кода дают один и тот же результат.

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

val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northampton")

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

class Tardis (var year: Int, var place: String)
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northampton")
fun main() {
    println(tardis1.year)
}

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

data class User (var username: String, var name: String, var age: Int)

Этот класс можно использовать напрямую.

 

data class User (var username: String, var name: String, var age: Int)
fun main() {
    val user1 = User ("River Song", "Melody Pond", 200)
    println("Username: " + user1.username)
    println("Name: " + user1.name)
    println("Age: " + user1.age)
}

Объекты

Объекты — это экземпляры в Kotlin, которые могут быть определены только один раз (singleton). Обычно они содержат переменные и функции. В принципе, вы создаете объект — подобно классу — всего одной строкой кода. Однако в этом случае объект пуст. Вы предоставляете содержимое объекта в его теле.

object myObject {
  fun sum(a: Int, b: Int): Int {
    return a+b
  }
}

Циклы

В Kotlin вы можете выбирать между тремя различными типами циклов: «while», «do…while» и «if». Они ведут себя так же, как их эквиваленты в других языках программирования. Цикл «while» выполняется до тех пор, пока не наступит заданное условие.

fun main() {
    var n = 1
    while (n <= 10) {
        println(n++)
    }
}

Цикл «do…while» ведет себя очень похоже на вариант «while». Разница в том, что содержимое цикла выполняется как минимум один раз, так как проверка происходит только в конце.

 

fun main() {
    var n = 1
    do {
        n++
    }  
    while (n < 1)
    println(n)
}

Цикл «for» выполняется до тех пор, пока условие остается истинным.

val myRange = 0..10
fun main() {
  for (n in myRange) {
    print("$n ")
  }
}

Условия

Kotlin знает три различных способа реализации условных операторов или ветвлений: «если», «если…else» и «когда». Запрос «if» позволяет компьютеру выполнить задачу, если условие истинно.

val whoCompanion = arrayOf("Bill Potts", "Clara Oswald", "Amy Pond", "Martha Jones", "Donna Noble", "Rose Tyler")
fun main() {
    if ("Rose Tyler" in whoCompanion) {
        print("yes")
    }
}

Используйте «else», чтобы добавить действие, которое должно быть выполнено, если условие не выполняется.

 

val whoCompanions9 = arrayOf("Rose Tyler")
val whoCompanions10 = arrayOf("Martha Jones", "Donna Noble", "Rose Tyler")
val whoCompanions11 = arrayOf("Clara Oswald", "Amy Pond")
val whoCompanions12 = arrayOf("Bill Potts", "Clara Oswald")

fun main() {
    var whoCompanion = "Clara Oswald"
    if (whoCompanion in whoCompanions9) {
        print("yes")
    }
    else {
        print("no")
    }
}

Наконец, выражение «when» является особенностью Kotlin: различные действия выполняются в зависимости от различных состояний. Таким образом, выражение «when» похоже на то, что решает «switch» в других языках программирования, но работает более точно.

Когда речь идет о теле «when», используются различные контрольные случаи. Они всегда связаны с определенной переменной.

var age = 17
fun main() {
   when {
      age > 18 -> println("You are too old!")
      age == 18 -> println("Already grown up!")
      age == 17 -> println("Welcome!")
      age <= 16 -> println("You are too young!")
   }
}

Однако аргумент также может быть передан непосредственно в «when», и его не нужно повторять каждый раз в теле. Кроме того, одно условие может вызывать несколько действий. Поэтому создается новое тело с фигурными скобками. Чтобы исключить неожиданные случаи, вам поможет «else».

fun multi(a: Int, b: Int, c: Int): Int {
    return a*b*c
}

fun main() {
    val d = "yes"
    when (d) {
        "no" -> println("No calculation")
        "yes" -> {
            println("Start calculation") 
            println(multi(5, 2, 100))
            println("Calculation finished")
        }
    else -> println("Incorrect input")    
    }
}

Nullability

Большим раздражающим фактором при программировании на Java является ошибка NullPointerException. Она возникает, если вы ссылаетесь на объект, значение которого равно «null». Kotlin избегает этой проблемы, не позволяя переменным принимать значение null. Если это произойдет, при компиляции появится сообщение «Null не может быть значением не нулевого типа String» — или аналогичное соответствующее предупреждение.

Но бывают моменты, когда вы хотите использовать значение «null» осознанно. Для этого в Kotlin используется оператор безопасного вызова: «?».

fun main() {
  var password: String? = null
  print(password)
}

С его помощью вы явно даете Kotlin знать, что значение «null» является допустимым. После этого программа выведет значение «null». Однако если вы хотите обратиться к определенному свойству переменной, вам придется снова использовать оператор безопасного вызова.

fun main() {
  var password: String? = null
  print(password?.length)
}

Также этот код снова выдаст «null», но ошибки не будет — программа все равно выполнится. Несколько элегантнее выглядит ситуация, когда вы указываете альтернативное значение. Для этого используется так называемый оператор Элвиса: «?:» — названный так потому, что смайл немного похож на челку.

fun main() {
    val firstName = null
    val lastName = "Pond"
  val name: String = firstName?: + " " + lastName?:
  print(name)
}

В этом примере информация выводится, когда переменная принимает значение «null».

Оцените статью
cdelat.ru
Добавить комментарий