{"id":20645046,"url":"https://github.com/romanow/kotlin-lecture","last_synced_at":"2026-06-04T19:31:30.426Z","repository":{"id":146005648,"uuid":"580721485","full_name":"Romanow/kotlin-lecture","owner":"Romanow","description":"Kotlin getting started lecture","archived":false,"fork":false,"pushed_at":"2022-12-21T13:10:26.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T15:54:36.904Z","etag":null,"topics":["kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Romanow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-21T09:27:08.000Z","updated_at":"2023-01-24T13:54:54.000Z","dependencies_parsed_at":"2023-05-24T22:13:25.870Z","dependency_job_id":null,"html_url":"https://github.com/Romanow/kotlin-lecture","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Romanow/kotlin-lecture","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkotlin-lecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkotlin-lecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkotlin-lecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkotlin-lecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Romanow","download_url":"https://codeload.github.com/Romanow/kotlin-lecture/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Romanow%2Fkotlin-lecture/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33917183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin"],"created_at":"2024-11-16T16:18:32.581Z","updated_at":"2026-06-04T19:31:30.401Z","avatar_url":"https://github.com/Romanow.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kotlin Language\n\n## Базовый синтаксис\n\n```kotlin\nprivate var commonSurnames = listOf(\"Morozov\", \"Ivanov\", \"Sidorov\")\n\nopen class Person(var name: String, var surname: String, private val gender: String) {\n    constructor(name: String, surname: String) : this(name, surname, \"Male\")\n\n    val male: Boolean\n        get() = gender.lowercase() === \"male\"\n\n    override fun toString(): String {\n        return \"Person(firstName='$name', lastName='$surname', gender='$gender')\"\n    }\n}\n\nclass Male(name: String, surname: String) : Person(name, surname)\n\nclass Female(name: String, surname: String) : Person(name, surname, \"female\")\n\nfun canChangeSurname(person: Person) =\n    if (!person.male) {\n        commonSurnames.any { person.surname.startsWith(it) }\n    } else {\n        false\n    }\n\nfun main() {\n    val male = Male(\"Alexey\", \"Romanov\")\n    val female = Female(\"Kate\", \"Morozova\")\n    val child = Person(\"Polina\", \"Romanova\", \"Female\")\n\n    println(male.surname in commonSurnames)\n    println(canChangeSurname(female))\n\n    female.surname = \"Romanova\"\n\n    for (i in 100 downTo 10 step 10) {\n        println(i)\n    }\n\n    val temp = 10\n    val result = when (temp) {\n        in 0..15 -\u003e \"cold\"\n        in 16..22 -\u003e \"comfort\"\n        else -\u003e \"uncomfortable\"\n    }\n    println(result)\n\n    val text = \"\"\"\n        Скажи-ка дядя, ведь недаром\n        Москву спалили перегаром\n    \"\"\".trimIndent()\n\n    println(text)\n}\n```\n\n### `data class`\n\n```kotlin\ndata class Pair\u003cL, R\u003e(\n    var left: L,\n    var right: R\n)\n\nfun main() {\n    val pair = Pair(10, \"Hello\")\n    println(pair)\n    val (left, right) = pair\n    println(\"Left: $left, right: $right\")\n}\n```\n\n### Properties\n\n```kotlin\nenum class TemperatureType { CELSIUS, FAHRENHEIT }\n\nclass Temperature(\n    private val degrees: Double,\n    private val type: TemperatureType,\n) {\n    val celsius: Double\n        get() {\n            return if (type == TemperatureType.CELSIUS) {\n                degrees\n            } else {\n                (degrees - 32.0) * 5.0 / 9.0\n            }\n        }\n\n    val fahrenheit: Double\n        get() {\n            return if (type == TemperatureType.FAHRENHEIT) {\n                degrees\n            } else {\n                degrees * 9.0 / 5.0 + 32.0\n            }\n        }\n}\n\nfun main() {\n    val temperature = Temperature(10.0, TemperatureType.CELSIUS)\n    println(temperature.celsius)\n    println(temperature.fahrenheit)\n}\n```\n\n### Getter and Setter\n\n```kotlin\nprivate enum class StorageType { HDD, SSD, TAPE }\n\nclass DataStorage {\n    private var storage: StorageType = StorageType.HDD\n\n    var storageType: String\n        get() = storage.name\n        set(value) {\n            if (storageType !in StorageType.values().map { it.name }) {\n                throw IllegalArgumentException(\"$value not in ${StorageType.values()}\")\n            }\n            storage = StorageType.valueOf(value)\n        }\n}\n\nfun main() {\n    val dataStorage = DataStorage()\n    println(dataStorage.storageType)\n    dataStorage.storageType = \"SSD\"\n    println(dataStorage.storageType)\n}\n```\n\n## Scope functions\n\nKotlin содержит несколько функций, единственной целью которых является выполнение блока кода в контексте объекта. Эти\nфункции формируют временную область видимости для объекта, к которому были применены, и вызывают код, указанный в\nпереданном лямбда-выражении. В этой области видимости можно получить доступ к объекту без явного к нему обращения по\nимени. Такие функции называются функциями области видимости (англ. scope functions). Всего их пять: `let`,\n`run`, `with`, `apply`, и `also`.\n\n#### let\n\nКонтекстный объект доступен в качестве аргумента (`it`).\n\nВозвращаемое значение - результат выполнения лямбды.\n\nЕсли значение переменной вычислялось при помощи цепочки операций, то `let` позволяет использовать полученный результат\nдля вызова одной или нескольких функций в блоке кода.\n\n`let` часто используется для выполнения блока кода только с not `null` значениями: `?.let { }`.\n\n#### with\n\nНе является функцией-расширением. Контекстный объект передается в качестве аргумента, а внутри лямбда-выражения он\nдоступен как получатель (`this`).\n\nВозвращаемое значение - результат выполнения лямбды.\n\nФункцию `with` рекомендуется использовать для вызова функций контекстного объекта без предоставления результата лямбды.\nВ коде with может читаться как \"_с этим объектом, сделайте следующее_\"\n\n#### run\n\nКонтекстный объект доступен в качестве получателя (`this`).\n\nВозвращаемое значение - результат выполнения лямбды.\n\n`run` делает то же самое, что и `with`, но вызывается как `let` - как функция расширения контекстного объекта. `run`\nудобен, когда лямбда содержит и инициализацию объекта, и вычисление возвращаемого значения.\n\n#### apply\n\nКонтекстный объект доступен в качестве получателя (`this`).\n\nВозвращаемое значение - контекстный объект.\n\n`apply` используется для такого блока кода, который не возвращает значение и в основном работает с членами\nобъекта-получателя. Типичный способ использования функции `apply` - настройка объекта-получателя.\n\n#### also\n\nКонтекстный объект доступен в качестве аргумента (`it`).\n\nВозвращаемое значение - контекстный объект.\n\n`also` подходит для выполнения таких действий, которые принимают контекстный объект в качестве аргумента. То есть, эту\nфункции следует использовать, когда требуется ссылка именно на объект, а не на его свойства и функции. Либо, когда\nтребуется чтобы была доступна ссылка на `this` из внешней области видимости.\n\n#### резюме\n\nКраткое руководство по выбору функции области видимости в зависимости от предполагаемого назначения:\n\n* Выполнение лямбды для not `null` объектов: `let`.\n* Представление переменной в виде выражения со своей локальной областью видимости: `let`.\n* Настройка объекта: `apply`.\n* Настройка объекта и вычисление результата: `run`.\n* Выполнение операций, для которых требуется выражение: `run` без расширения.\n* Применение дополнительных значений: `also`.\n* Группировка всех функций, вызываемых для объекта: `with`.\n\n## Nullability and Elvis Operator\n\n```kotlin\nfun main() {\n    val a: String = \"Hello, world\"\n    println(a.lowercase())\n    // a = null\n\n    val b: String? = null\n    println(b?.lowercase())\n    val c: String? = b ?: \"empty\"\n    println(c)\n\n    println(c!!.lowercase())\n}\n```\n\n```kotlin\nfun lower(s: String?) = s?.lowercase() ?: \"empty\"\n\nfun main() {\n    lower(null) // empty\n    lower(\"ABC\") // abc\n}\n```\n\n## Extensions\n\n```kotlin\nfun String.quoted() = \"'$this'\"\nfun String.wrap(tag: String) = \"\u003c$tag\u003e$this\u003c/$tag\u003e\"\n\nfun String?.isNullOrEmpty() = this == null || isEmpty()\n\nfun main() {\n    println(\"cat\".quoted()) // 'cat'\n    println(\"cat\".wrap(\"animal\")) // \u003canimal\u003ecat\u003c/animal\u003e\n}\n```\n\n## ️Named Arguments\n\n```kotlin\nfun color(red: Int = 0, green: Int = 0, blue: Int = 0) = \"RGB($red, $green, $blue)\"\n\nfun main() {\n    println(color(139)) // RGB(139, 0, 0)\n    println(color(blue = 139)) // RGB(0, 0, 139)\n    println(color(255, 165)) // RGB(255, 165, 0)\n    println(color(red = 128, blue = 128)) // RGB(128, 0, 128)\n}\n```\n\n### High order functions\n\n```kotlin\nfun \u003cT\u003e List\u003cT\u003e.log(filter: (T) -\u003e Boolean, action: (index: Int, item: T) -\u003e Unit) {\n    this.filter(filter).forEachIndexed(action)\n}\n\nfun main() {\n    val items = List(10) { it * it }\n    items.log({ it \u003e 0 }, { index, item -\u003e println(\"$index: $item\") })\n}\n```\n\n```kotlin\nfun \u003cA, B, C\u003e ((A) -\u003e B).andThen(action: (B) -\u003e C): (A) -\u003e C = { a: A -\u003e action(this(a)) }\n\nfun main() {\n    val exp: (Int) -\u003e Int = { x: Int -\u003e x * x }\n    val println: (Int) -\u003e Unit = { i: Int -\u003e println(\"Result: $i\") }\n\n    exp.andThen(println).invoke(5)\n}\n```\n\n## Задания\n\nУстановить [EduTools](https://plugins.jetbrains.com/plugin/10081-edutools): `File` -\u003e `Settings` -\u003e `plugins`\n-\u003e `Marketplace` -\u003e` EduTools`, перезагрузить IDE.\n\nНачать обучение: `File` -\u003e `Learn and Teach` -\u003e `Browse Courсes` -\u003e `Marketplace` -\u003e в поиске выберете нужный курс.\n\n* Базовый курс: _Kotlin Basic_.\n* Полный курс по Kotlin: _AtomicKotlin_.\n\n## Ссылки\n\n1. [Руководство по языку Kotlin](https://kotlinlang.ru/)\n3. [Learner start guide](https://plugins.jetbrains.com/plugin/10081-edutools/docs/learner-start-guide.html)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromanow%2Fkotlin-lecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fromanow%2Fkotlin-lecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fromanow%2Fkotlin-lecture/lists"}