Kotlin

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 20:09, 1 июня 2016.
Kotlin
Спроектировано JetBrains
Первый   появившийся 2016
Предварительный выпуск 1.0 RC / 04.02.2016
Печать дисциплины статическая
Платформа Java Virtual Machine
OS любая, поддерживающая JVM
Портал: http://kotlinlang.org/
Под влиянием
Java, Scala, Groovy, Gosu, Ceylon, C#

Kotlin (Ко́тлин) — статически типизированный язык программирования, работающий поверх JVM, и разрабатываемый компанией JetBrains. Язык также компилируется и в JavaScript. При создании ставилась цель создать язык более лаконичный и типобезопасный, чем Java, и более простой, чем Scala. Следствием упрощения по сравнению со Scala стали ускоренная компиляция и улучшенная поддержка языка в IDE. Язык разрабатывается с 2010 года, представлен публике в июле 2011. Исходный код открыли в феврале 2012, и в этом же месяце был выпущен milestone 1, включающий плагин для IDEA. В июне — milestone 2 с поддержкой Android. В декабре 2012 года вышел milestone 4, включающий, в частности, поддержку Java 7. По состоянию на ноябрь 2015 года основные возможности языка стабилизированы, готовится выпуск версии 1.0.

Классы

Чтобы создать класс в Kotlin, вы должны использовать ключевое слово class. Например, вот так можно создаеть пустой класс с именем Person:

class Person {
}

Добавление свойств

Класс обычно имеет свойства и функции-члены (также называемые методы). Добавим два свойства в класс Person, имя типа String и возраст типа Int

var name: String = ""
var age: Int = 0

Как можно видеть, синтаксис для создания переменных немного отличается от Java. Чтобы создать переменную в Kotlin, надо использовать var ключевое слово. Тем не менее, если вы хотите, чтобы переменная была только для чтения или однократно назначить переменную, используйте ключевое слово val.

Ради нулевой безопасности, Kotlin также делает различие между переменными, которые могут быть null и переменные, которые никогда не могут быть null В нашем предыдущем примере, и переменные name и age не может быть null Если они равны нулю, то компилятор выдаст ошибку.

Чтобы создать переменную, которая может содержать null необходимо добавить ? после типа переменной. Например:

var college: String? = null

Создать экземпляр класса просто. Для создания экземпляра класса ключевое слово new не указывается. После того, как экземпляр был создан, можете получить доступ к его свойства так же, как в Java:

var jake = Person()
jake.name = "Jake Hill"
jake.age = 24
jake.college = "Stephen's College"

Использование конструкторов

Синтаксис Kotlin, позволяет создать компактный конструктор:

class Person(var name: String, var age: Int, var college: String?) {
}

Чтобы добавить дополнительные конструкторы в класс, известные как вторичные конструкторы, надо использовать ключевое слово constructor. Вторичные конструкторы должны делегировать первичный конструктор, используя ключевое слово this. Добавим вторичный конструктор в наш класс:

class Person(var name: String, var age: Int, var college: String?) {
   var email: String = ""
   constructor(name:String, age:Int, college: String?, email: String) : this(name, age, college) {
      this.email = email
   }
}

Создание экземпляра с помощью вторичного конструктора:

var jake = Person("Jake Hill", 24, "Stephen's College", "jake.hill@example.com")

Добавление функции-члена

В Kotlin, функции создаются с помощью ключевое слово fun. Добавим простую функцию-член с именем isEligibleToVote, которая возвращает Boolean значение:

fun isEligibleToVote(): Boolean {
   // If age is greater or equal to 18
   // return true 
   return age >= 18
}

Вызов метода так же, как в Java:

jake.isEligibleToVote()

Создание расширений

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

Например, чтобы добавить расширение под названием isTeenager к классу Person, можно написать следующий код вне класса:

fun Person.isTeenager(): Boolean {
   // If age falls in the range
   // 13-19 return true 
   return age in 13..19
}

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

fun String.containsSpaces(): Boolean {
   return this.indexOf(" ")!=-1
}

Создание производных классов

Важно иметь в виду следующее при создании производного класса:

  • Необходимо использовать : (в Java ключевое слово extends).
  • Заголовок базового класса должен иметь open аннотацию.
  • Если базовый класс имеет конструктор, который принимает параметры, производный класс должен инициализировать эти параметры в самом заголовке.

Создадим класс с именем Employee, производный от Person:

open class Person(var name: String, var age: Int, var college: String?) {
   ...
}
class Employee(name: String, age: Int, college: String?, var company: String) : Person(name, age, college) {
}

Переопределение функции-члена

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

Например, чтобы переопределить isEligibleToVote метод, можно добавить следующий фрагмент кода в Employee класса:

override fun isEligibleToVote(): Boolean {
   // Always return true
   return true
}

Создание статических методов

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

main метод является, пожалуй, самый известным статическим методом. Если нужно добавить main метод для пакета с именем com.tutsplus.code.tutorial, то ваш код будет выглядеть следующим образом:

package com.tutsplus.code.tutorial

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

Функции

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

Создание одиночного выражения функции

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

Например, чтобы добавить метод к классу Person, который возвращает true, если у человека возраст в районе восьмидесяти лет, можно было бы написать:

fun isOctogenarian(): Boolean = age in 80 .. 89

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

Функции высшего порядка и лямбда-выражения

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

Рассмотрим следующий пример, который демонстрирует синтаксис лямбда-выражения:

{x, y -> x+y}

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

val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
val actualSum = sumLambda(3,4)

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

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

fun doubleTheResult(x:Int, y:Int, f:(Int, Int)->Int): Int {
   return f(x,y) * 2
}

Эту функцию можно вызвать следующим образом:

val result1 = doubleTheResult(3, 4, sumLambda)

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

val result2 = doubleTheResult(3, 4, {x,y -> x+y})

Лямбда-выражения часто используются с массивами. Например, рассмотрим следующий массив значений Int:

val numbers:Array<Int> = arrayOf(1, 2, 3, 4, 5)

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

val squaredNumbers = numbers.map({x -> x * x})
// Result will be a new array that contains
// 1, 4, 9, 16, 25

Диапазоны

Диапазоны выражений очень часто используют в Kotlin.

Чтобы создать диапазон, все, что нужно, это оператор ...

val r1 = 1..5
// This range contains the number 1, 2, 3, 4, 5

Чтобы создать ряд в порядке убывания, используйте downTo вместо функции.

val r2 = 5 downTo 1 
// This range contains the number 5, 4, 3, 2, 1

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

val r3 = 5 downTo 1 step 2
// This range contains the number 5, 3, 1

Условные конструкции

if

В Kotlin, if это выражение, которое возвращает разные значения в зависимости от того было ли выполнено условие. Следующий пример иллюстрирует, как это работает.

var age = 20
val isEligibleToVote = if(age > 18) "Yes" else "No"
// isEligibleToVote will now be set to "Yes"

when

when выражение эквивалентно switch в Java. Тем не менее, when более гибок. Рассмотрим следующий пример.

val age = 17

val typeOfPerson = when(age){
   0 -> "New born"
   in 1..12 -> "Child"
   in 13..19 -> "Teenager"
   else -> "Adult"
}
// typeOfPerson will now be set to "Teenager"

Циклические конструкции

for..in

В Kotlin, можно использовать for..in циклы для перебора массивов, коллекций, и всего остального, что обеспечивает итератор. Его синтаксис практически идентичен Java, за исключением оператора in. В следующем примере показано, как перебрать массив String объектов.

val names = arrayOf("Jake", "Jill", "Ashley", "Bill")
for (name in names) {
   println(name)
}

С помощью выражений диапазонов, можно сделать этот цикл традиционным, C-стиле, for циклы.

for (i in 0..9) {
   println(i)
}
// Behaves exactly like
for(int i=0;i<10;i++)

while и do..while

Синтаксис while и do..while Kotlin идентичен синтаксису, используемому в Java. Например, следующий код Kotlin перебирает массив String объектов с использованием цикла while:

val names = arrayOf("Jake", "Jill", "Ashley", "Bill")
var i = names.size()
while(i>0) {
   println(names[--i])
}

Шаблоны строк

Kotlin позволяет встраивать переменные и выражения в строках, обернув их в паре фигурных скобок, с префиксом символа $. Например:

val name = "Bob"
println("My name is ${name}") // Prints "My name is Bob"

val a = 10
val b = 20
println("The sum is ${a+b}") // Prints "The sum is 30"

Ссылки