Skip to main content

Kotlin Syntax

Основы Kotlin

Функция main()

fun main() {
println("Greetings")
// Код начинается здесь
}

Функция main() является точкой входа в каждую программу Kotlin и должна быть включена в код перед выполнением.

Вывод в консоль

println("Greetings, earthling!")
print("Take me to ")
print("your leader.")

/*
Вывод:
Greetings, earthling!
Take me to your leader.
*/

Комментарии

// это однострочный комментарий

/*
этот
комментарий
для
нескольких
строк
*/

Порядок выполнения

fun main() {
println("Я буду напечатан первым.")
println("Я буду напечатан вторым.")
println("Я буду напечатан третьим.")
}

Переменные и типы данных

Мутабельность

var mutableString: String = "Adam"  // изменяемая
val immutableString: String = "Adam" // неизменяемая
val inferredString = "Adam" // тип выводится автоматически

Числа

val intNum = 10      // Int
val doubleNum = 10.0 // Double
val longNum = 10L // Long
val floatNum = 10.0F // Float

Булевы значения

val trueBoolean = true
val falseBoolean = false
val andCondition = trueBoolean && falseBoolean
val orCondition = trueBoolean || falseBoolean

Строки

val name = "Adam"
val greeting = "Hello, " + name // конкатенация
val greetingTemplate = "Hello, $name" // шаблонная строка
val interpolated = "Hello, ${name.toUpperCase()}" // интерполяция с выражением

Встроенные свойства и функции строк

var monument = "the Statue of Liberty"

println(monument.capitalize()) // The Statue of Liberty
println(monument.length) // 21

Экранирование символов

print("\"Excellent!\" I cried. \"Elementary,\" said he.")

// Вывод: "Excellent!" I cried. "Elementary," said he.
  • \n - новая строка
  • \t - табуляция
  • \r - возврат каретки
  • \' - одинарная кавычка
  • \" - двойная кавычка
  • \\ - обратная косая черта
  • \$ - знак доллара

Статические поля

class Person {
companion object {
val NAME_KEY = "name_key"
}
}

val key = Person.NAME_KEY

Арифметические операции

Операторы

5 + 7  // 12 - сложение
9 - 2 // 7 - вычитание
8 * 4 // 32 - умножение
25 / 5 // 5 - деление
31 % 2 // 1 - остаток от деления

Порядок операций

5 + 8 * 2 / 4 - 3 // 6
3 + (4 + 4) / 2 // 7
4 * 2 + 1 * 7 // 15
3 + 18 / 2 * 1 // 12
6 - 3 % 2 + 2 // 7

Составные операторы присваивания

var batteryPercentage = 80

// длинный синтаксис
batteryPercentage = batteryPercentage + 10

// короткий синтаксис с составным оператором
batteryPercentage += 10

Инкремент и декремент

var year = 2019
year++ // 2020
year-- // 2019

Математическая библиотека

Math.pow(2.0, 3.0) // 8.0 - возведение в степень
Math.min(6, 9) // 6 - минимум
Math.max(10, 12) // 12 - максимум
Math.round(13.7) // 14 - округление

Null-безопасность

Nullable vs Not-Nullable

val cannotBeNull: String = null // Ошибка компиляции
val canBeNull: String? = null // Допустимо

val cannotBeNull: Int = null // Ошибка компиляции
val canBeNull: Int? = null // Допустимо

Проверка на null

val name: String? = "Adam"

if (name != null && name.length > 0) {
print("Длина строки: ${name.length}")
} else {
print("Строка пуста.")
}

Безопасный оператор

val nullableStringLength: Int? = nullableString?.length
val nullableDepartmentHead: String? = person?.department?.head?.name

Цепочка безопасных вызовов

bob?.department?.head?.name // цепочка возвращает null, если любое свойство null

Оператор Elvis

val nonNullStringLength: Int = nullableString?.length ?: 0
val nonNullDepartmentHead: String = person?.department?.head?.name ?: ""
val nonNullDepartmentHead: String = person?.department?.head?.name.orEmpty()

Безопасные приведения типов

// Не выбросит ClassCastException
val nullableCar: Car? = (input as? Car)

Оператор утверждения не-null

val l = b!!.length // выбросит NullPointerException, если b равен null

Коллекции

Создание

val numArray = arrayOf(1, 2, 3)
val numList = listOf(1, 2, 3)
val mutableNumList = mutableListOf(1, 2, 3)

Доступ к элементам

val firstItem = numList[0]
val firstItem = numList.first()
val firstItem = numList.firstOrNull()

Размер коллекции

var worldContinents = listOf("Asia", "Africa", "North America", "South America", "Antarctica", "Europe", "Australia")

println(worldContinents.size) // 7

Манипуляции со списками

var seas = listOf("Black Sea", "Caribbean Sea", "North Sea")
println(seas.contains("North Sea")) // true

// Функция contains() выполняет операцию чтения на любом списке
// seas.add("Baltic Sea") // Ошибка: нельзя записывать в неизменяемый список

Мутабельность

val immutableList = listOf(1, 2, 3)
val mutableList = immutableList.toMutableList()

val immutableMap = mapOf("Jack" to 11, "Queen" to 12, "King" to 13)
val mutableMap = immutableMap.toMutableMap()

Итерация

for (item in myList) {
print(item)
}

myList.forEach {
print(it)
}

myList.forEachIndexed { index, item ->
print("Элемент на позиции $index: $item")
}

Фильтрация и поиск

val evenNumbers = numList.filter { it % 2 == 0 }
val containsEven = numList.any { it % 2 == 0 }
val containsNoEvens = numList.none { it % 2 == 0 }
val allOdd = numList.all { it % 2 == 1 }
val firstEvenNumber: Int = numList.first { it % 2 == 0 }
val firstEvenOrNull: Int? = numList.firstOrNull { it % 2 == 0 }
val fullMenu = objList.map { "${it.name} - $${it.detail}" }

Примечание: it - это неявное имя для единственного параметра.

Множества (Sets)

var primaryColors = setOf("Red", "Blue", "Yellow")
var womenInTech = mutableSetOf("Ada Lovelace", "Grace Hopper", "Radia Perlman", "Sister Mary Kenneth Keller")

Доступ к элементам коллекций

var companies = setOf("Facebook", "Apple", "Netflix", "Google")

println(companies.elementAt(3)) // Google
println(companies.elementAt(4)) // Ошибка
println(companies.elementAtOrNull(4)) // null

Карты (Maps)

val faceCards = mutableMapOf("Jack" to 11, "Queen" to 12, "King" to 13)
val jackValue = faceCards["Jack"] // 11
faceCards["Ace"] = 1

var averageTemp = mapOf("winter" to 35, "spring" to 60, "summer" to 85, "fall" to 55)

Получение ключей и значений карты

var oscarWinners = mutableMapOf("Parasite" to "Bong Joon-ho", "Green Book" to "Jim Burke", "The Shape Of Water" to "Guillermo del Toro")

println(oscarWinners.keys)
// [Parasite, Green Book, The Shape Of Water]

println(oscarWinners.values)
// [Bong Joon-ho, Jim Burke, Guillermo del Toro]

println(oscarWinners["Parasite"])
// Bong Joon-ho

Добавление и удаление элементов карты

var worldCapitals = mutableMapOf("United States" to "Washington D.C.", "Germany" to "Berlin", "Mexico" to "Mexico City", "France" to "Paris")

worldCapitals.put("Brazil", "Brasilia")
println(worldCapitals)
// {United States=Washington D.C., Germany=Berlin, Mexico=Mexico City, France=Paris, Brazil=Brasilia}

worldCapitals.remove("Germany")
println(worldCapitals)
// {United States=Washington D.C., Mexico=Mexico City, France=Paris, Brazil=Brasilia}

Функции

Параметры и возвращаемые типы

fun printName() {
print("Adam")
}

fun printName(person: Person) {
print(person.name)
}

fun getGreeting(person: Person): String {
return "Hello, ${person.name}"
}

fun getGreeting(person: Person): String = "Hello, ${person.name}"
fun getGreeting(person: Person) = "Hello, ${person.name}"

Параметры по умолчанию

fun getGreeting(person: Person, intro: String = "Hello,"): String {
return "$intro ${person.name}"
}

// Возвращает "Hello, Adam"
val hello = getGreeting(Person("Adam"))

// Возвращает "Welcome, Adam"
val welcome = getGreeting(Person("Adam"), "Welcome,")

Именованные параметры

fun findMyAge(currentYear: Int, birthYear: Int) {
var myAge = currentYear - birthYear
println("Мне $myAge лет.")
}

fun main() {
findMyAge(currentYear = 2020, birthYear = 1995)
// Мне 25 лет.
findMyAge(birthYear = 1920, currentYear = 2020)
// Мне 100 лет.
}

Оператор return

// Возвращаемый тип объявляется вне скобок
fun getArea(length: Int, width: Int): Int {
var area = length * width
return area
}

fun main() {
var myArea = getArea(10, 8)
println("Площадь равна $myArea.")
// Площадь равна 80.
}

Функции-выражения

fun fullName(firstName: String, lastName: String) = "$firstName $lastName"

fun main() {
println(fullName("Ariana", "Ortega"))
// Ariana Ortega
println(fullName("Kai", "Gittens"))
// Kai Gittens
}

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

fun callbackIfTrue(condition: Boolean, callback: () -> Unit) {
if (condition) {
callback()
}
}

callbackIfTrue(someBoolean) {
print("Условие было истинным")
}

Функции-расширения

fun Int.timesTwo(): Int {
return this * 2
}

val four = 2.timesTwo()

Функциональные литералы

fun main() {
// Анонимная функция:
var getProduct = fun(num1: Int, num2: Int): Int {
return num1 * num2
}
println(getProduct(8, 3))
// 24

// Лямбда-выражение
var getDifference = { num1: Int, num2: Int -> num1 - num2 }
println(getDifference(10, 3))
// 7
}

Статические функции

class Fragment(val args: Bundle) {
companion object {
fun newInstance(args: Bundle): Fragment {
return Fragment(args)
}
}
}

val fragment = Fragment.newInstance(args)

Классы

Простой класс

// класс со свойствами, содержащими значения по умолчанию
class Student {
var name = "Lucia"
var semester = "Fall"
var gpa = 3.95
}

// сокращенный синтаксис без тела класса
class Student

Создание экземпляра

// Класс
class Student {
var name = "Lucia"
var semester = "Fall"
var gpa = 3.95
}

fun main() {
var student = Student()
// Экземпляр
println(student.name)
// Lucia
println(student.semester)
// Fall
println(student.gpa)
// 3.95
}

Первичный конструктор

class Person(val name: String, val age: Int)
val adam = Person("Adam", 100)

class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int)

fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022)
println(student.name)
// Lucia
println(student.gpa)
// 3.95
println(student.semester)
// Fall
println(student.estimatedGraduationYear)
// 2022
}

Вторичные конструкторы

class Person(val name: String) {
private var age: Int? = null

constructor(name: String, age: Int) : this(name) {
this.age = age
}
}

// Выше можно заменить параметрами по умолчанию
class Person(val name: String, val age: Int? = null)

Блок инициализации

class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int) {
init {
println("$name имеет ${estimatedGraduationYear - 2020} лет до окончания колледжа.")
}
}

fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022)
// Lucia имеет 2 года до окончания колледжа.
}

Функции-члены

class Student(val name: String, val gpa: Double, val semester: String, val estimatedGraduationYear: Int) {

init {
println("$name имеет ${estimatedGraduationYear - 2020} лет до окончания колледжа.")
}

// функция-член
fun calculateLetterGrade(): String {
return when {
gpa >= 3.0 -> "A"
gpa >= 2.7 -> "B"
gpa >= 1.7 -> "C"
gpa >= 1.0 -> "D"
else -> "E"
}
}
}

fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022)
// Lucia имеет 2 года до окончания колледжа.
println("Буквенная оценка ${student.name}: ${student.calculateLetterGrade()}.")
// Буквенная оценка Lucia: A.
}

Наследование и реализация

open class Vehicle
class Car : Vehicle()

interface Runner {
fun run()
}

class Machine : Runner {
override fun run() {
// ...
}
}

Управляющие конструкции

Условные выражения

var morning = true

if (morning) {
println("Вставай и сияй!")
}
// Вставай и сияй!

Else-выражения

var rained = false

if (rained) {
println("Не нужно поливать растения сегодня.")
} else {
println("Растения нужно полить!")
}
// Растения нужно полить!

Else-If выражения

var age = 65

if (age < 18) {
println("Вы считаетесь несовершеннолетним")
} else if (age < 60) {
println("Вы считаетесь взрослым")
} else {
println("Вы считаетесь пожилым")
}
// Вы считаетесь пожилым

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

var myAge = 19
var sisterAge = 11
var cousinAge = 11

myAge > sisterAge // true
myAge < cousinAge // false
myAge >= cousinAge // true
myAge <= sisterAge // false

Логические операторы

var humid = true
var raining = true
var jacket = false

println(!humid) // false
println(jacket && raining) // false
println(humid || raining) // true

Оператор AND: &&

var humid = true
var raining = true
var shorts = false
var sunny = false

// true AND true
println(humid && raining) // true
// true AND false
println(humid && shorts) // false
// false AND true
println(sunny && raining) // false
// false AND false
println(shorts && sunny) // false

Оператор OR: ||

var late = true
var skipBreakfast = true
var underslept = false
var checkEmails = false

// true OR true
println(skipBreakfast || late) // true
// true OR false
println(late || checkEmails) // true
// false OR true
println(underslept || late) // true
// false OR false
println(checkEmails || underslept) // false

Оператор NOT

var hungry = true
var full = false

println(!hungry) // false
println(!full) // true

Порядок вычисления

!true && (false || true) // false
/*
(false || true) вычисляется первым и возвращает true.
Затем вычисляется !true && true и возвращает окончательный результат false
*/

!false && true || false // true
/*
!false вычисляется первым и возвращает true.
Затем вычисляется true && true, возвращая true.
затем true || false вычисляется и в итоге возвращает true
*/

Вложенные условия

var studied = true
var wellRested = true

if (wellRested) {
println("Удачи сегодня!")
if (studied) {
println("Ты должен быть готов к экзамену!")
} else {
println("Потрать несколько часов на изучение перед экзаменом!")
}
}

// Вывод: Удачи сегодня!
// Вывод: Ты должен быть готов к экзамену!

Циклы for

for (i in 0..10) { }        // 0 - 10
for (i in 0 until 10) { } // 0 - 9
(0..10).forEach { }
for (i in 0 until 10 step 2) { } // 0, 2, 4, 6, 8

Циклы while

while (x > 0) {
x--
}

do {
x--
} while (x > 0)

Выражение when

var grade = "A"

when (grade) {
"A" -> println("Отличная работа!")
"B" -> println("Хорошая работа!")
"C" -> println("Ты сдал!")
else -> println("Близко! Обязательно подготовься больше в следующий раз!")
}
// Отличная работа!

Оператор диапазона

var height = 46 // дюймы

if (height in 1..53) {
println("Извините, вы должны быть не менее 54 дюймов для катания на горке")
}
// Извините, вы должны быть не менее 54 дюймов для катания на горке

Операторы равенства

var myAge = 22
var sisterAge = 21

myAge == sisterAge // false
myAge != sisterAge // true

Деструктурирующие объявления

Объекты и списки

val person = Person("Adam", 100)
val (name, age) = person

val pair = Pair(1, 2)
val (first, second) = pair

val coordinates = arrayOf(1, 2, 3)
val (x, y, z) = coordinates

Функции componentN

class Person(val name: String, val age: Int) {
operator fun component1(): String {
return name
}

operator fun component2(): Int {
return age
}
}

Ссылки