Kotlin ( / ˈ k ɒ t l ɪ n / ) [ 2] — кроссплатформенный , статически типизированный , высокоуровневый язык программирования общего назначения с выводом типов . Kotlin разработан для полного взаимодействия с Java , а версия JVM стандартной библиотеки Kotlin зависит от библиотеки классов Java , но вывод типов позволяет сделать его синтаксис более лаконичным. Kotlin в основном нацелен на JVM, но также компилируется в JavaScript (например, для веб-приложений frontend, использующих React ) [3] или в машинный код через LLVM (например, для нативных приложений iOS , разделяющих бизнес-логику с приложениями Android ). [4] Расходы на разработку языка несет JetBrains , в то время как Kotlin Foundation защищает торговую марку Kotlin. [5]
7 мая 2019 года Google объявила, что язык программирования Kotlin теперь является предпочтительным языком для разработчиков приложений Android . [6] С момента выпуска Android Studio 3.0 в октябре 2017 года Kotlin был включен в качестве альтернативы стандартному компилятору Java. Компилятор Android Kotlin по умолчанию создает байт-код Java 8 (который работает в любой более поздней JVM), но позволяет программисту выбрать Java 9 до 20 для оптимизации [7] или предоставляет больше функций; имеет поддержку взаимодействия классов двунаправленных записей для JVM, представленную в Java 16, считающуюся стабильной с Kotlin 1.5.
Kotlin поддерживает веб с помощью Kotlin/JS через промежуточный бэкэнд на основе представления , который был объявлен стабильным с версии 1.8, выпущенной в декабре 2022 года. Kotlin/Native (например, для поддержки Apple Silicon ) был объявлен стабильным с версии 1.9.20, выпущенной в ноябре 2023 года. [8] [9]
Название происходит от острова Котлин , российского острова в Финском заливе , недалеко от Санкт-Петербурга . Андрей Бреслав, бывший ведущий дизайнер Kotlin, упомянул, что команда решила назвать его в честь острова, так же как язык программирования Java был назван в честь индонезийского острова Ява [10] (хотя, как говорят, название языка было навеяно «java» — американским сленговым словом для кофе, [11] которое само по себе произошло от названия острова). [12]
В июле 2011 года JetBrains представила Project Kotlin, новый язык для JVM, который находился в разработке в течение года. [13] Руководитель JetBrains Дмитрий Жемеров сказал, что большинство языков не обладают функциями, которые они искали, за исключением Scala . Однако он сослался на медленное время компиляции Scala как на недостаток. [13] Одна из заявленных целей Kotlin — компилировать так же быстро, как Java. В феврале 2012 года JetBrains открыла исходный код проекта под лицензией Apache 2. [14]
JetBrains надеялась, что новый язык будет способствовать продажам IntelliJ IDEA . [15]
Первая фиксация в репозитории Kotlin Git была сделана 8 ноября 2010 года. [16]
Kotlin 1.0 был выпущен 15 февраля 2016 года. [17] Это считается первым официально стабильным релизом, и JetBrains взяла на себя обязательство по долгосрочной обратной совместимости, начиная с этой версии.
На конференции Google I/O 2017 компания Google объявила о первоклассной поддержке Kotlin на Android . [18]
Kotlin 1.2 был выпущен 28 ноября 2017 года. [19] Функция совместного использования кода между платформами JVM и JavaScript была добавлена в этот релиз (мультиплатформенное программирование на данный момент является бета- функцией [20], улучшенной с «экспериментальной»). Была сделана полнофункциональная демонстрация с новым плагином Kotlin/JS Gradle. [21] [22]
Kotlin 1.3 был выпущен 29 октября 2018 года, добавив поддержку сопрограмм для использования с асинхронным программированием. [23]
7 мая 2019 года Google объявила, что язык программирования Kotlin теперь является предпочтительным языком для разработчиков приложений для Android. [6]
Kotlin 1.4 был выпущен в августе 2020 года, в том числе с некоторыми небольшими изменениями в поддержке платформ Apple, т. е. во взаимодействии Objective-C / Swift . [24]
Kotlin 1.5 был выпущен в мае 2021 года.
Kotlin 1.6 был выпущен в ноябре 2021 года.
Kotlin 1.7 был выпущен в июне 2022 года, включая альфа- версию нового компилятора Kotlin K2 . [25]
Kotlin 1.8 был выпущен в декабре 2022 года, 1.8.0 был выпущен 11 января 2023 года. [26]
Kotlin 1.9 был выпущен в июле 2023 года, 1.9.0 был выпущен 6 июля 2023 года. [27]
Kotlin 2.0 был выпущен в мае 2024 года, 2.0.0 был выпущен 21 мая 2024 года. [28]
Руководитель разработки Андрей Бреслав заявил, что Kotlin разработан как объектно-ориентированный язык промышленного уровня и «лучший язык», чем Java , но при этом полностью совместимый с кодом Java, что позволяет компаниям постепенно мигрировать с Java на Kotlin. [29]
Заимствуя из Scala , точки с запятой необязательны в качестве завершающего признака оператора ; в большинстве случаев для компилятора достаточно новой строки , чтобы сделать вывод о том, что оператор завершен. [30]
Заимствуя из Scala , объявления переменных и списки параметров Kotlin имеют тип данных , указанный после имени переменной (и с разделителем двоеточием ), подобно Ada , BASIC , Pascal , TypeScript и Rust . Это, согласно статье Романа Елизарова, текущего руководителя проекта, приводит к выравниванию имен переменных и более приятно для глаз, особенно когда есть несколько объявлений переменных подряд, и один или несколько типов слишком сложны для вывода типа или должны быть объявлены явно для понимания людьми. [31] [32]
Заимствуя из Scala , переменные в Kotlin могут быть доступны только для чтения, объявлены с помощью ключевого слова val , или изменяемы , объявлены с помощью ключевого слова var . [33]
Заимствуя из Scala , члены класса по умолчанию являются открытыми, а сами классы по умолчанию являются окончательными , что означает, что создание производного класса невозможно, если базовый класс не объявлен с ключевым словом open .
В дополнение к классам и функциям-членам (которые эквивалентны методам) объектно-ориентированного программирования, Kotlin также поддерживает процедурное программирование с использованием функций . [34] Функции и конструкторы Kotlin поддерживают аргументы по умолчанию , списки аргументов переменной длины , именованные аргументы и перегрузку по уникальной сигнатуре. Функции-члены класса являются виртуальными, т. е. отправляются на основе типа времени выполнения объекта, для которого они вызываются.
Kotlin 1.3 добавил поддержку контрактов, [35] которые стабильны для деклараций стандартной библиотеки, но все еще экспериментальны для деклараций, определяемых пользователем. Контракты вдохновлены парадигмой программирования Design by Contract [36] Эйфеля .
После ScalaJS, код Kotlin может быть транспилирован в JavaScript , что позволяет обеспечить взаимодействие между кодом, написанным на двух языках. Это может быть использовано либо для написания полных веб-приложений на Kotlin, либо для совместного использования кода между бэкендом Kotlin и фронтендом JavaScript. [37]
Kotlin ослабляет ограничение Java, позволяющее статическим методам и переменным существовать только внутри тела класса. Статические объекты и функции могут быть определены на верхнем уровне пакета без необходимости в избыточном уровне класса. Для совместимости с Java Kotlin предоставляет аннотацию JvmName
, которая указывает имя класса, используемое при просмотре пакета из проекта Java. Например, @file:JvmName("JavaClassName")
.
Как и в C , C++ , C# , Java и Go , точкой входа в программу Kotlin является функция с именем «main», которой может быть передан массив, содержащий любые аргументы командной строки . Это необязательно, начиная с Kotlin 1.3. [38] Поддерживается интерполяция строк в стиле Perl , PHP и Unix shell . Также поддерживается вывод типов .
// Привет, мир! примервесело главное () { область действия = "Мир" println ( "Привет, $ scope !" )}fun main ( args : Array < String > ) { для ( аргумент в аргументах ) println ( аргумент )}
Подобно C#, Kotlin позволяет добавлять функцию расширения к любому классу без формальностей создания производного класса с новыми функциями. Функция расширения имеет доступ ко всем открытым интерфейсам класса, которые она может использовать для создания нового интерфейса функции для целевого класса. Функция расширения будет выглядеть точно так же, как функция класса, и будет показана в проверке автодополнения кода функций класса. Например:
пакет MyStringExtensions забавная строка.lastChar ( ) : Char = получить ( длина - 1 ) >>> println ( "Kotlin" .lastChar ( ))
Помещая предыдущий код на верхний уровень пакета, класс String расширяется и включает функцию lastChar
, которая не была включена в исходное определение класса String.
// Перегрузка оператора '+' с использованием функции расширенияоператор fun Point . plus ( other : Point ): Point { Точка возврата ( x + other.x , y + other.y ) }>>> значение p1 = Точка ( 10 , 20 ) >>> значение p2 = Точка ( 30 , 40 ) >>> println ( p1 + p2 ) Точка ( x = 40 , y = 60 )
В Kotlin есть пять функций области видимости, которые позволяют изменять область видимости в контексте объекта . Функции области видимости — это let
, run
, with
, apply
, и also
. [39]
Подобно Python, оператор распространения звездочка (*) распаковывает содержимое массива в виде отдельных аргументов функции, например:
fun main ( args : Array < String > ) { список значений = listOf ( "аргументы: " , * аргументы ) println ( список )}
Деструктурирующие объявления разлагают объект на несколько переменных одновременно, например, объект с двухмерными координатами может быть деструктурирован на два целых числа x и y .
Например, Map.Entry
объект поддерживает деструктуризацию для упрощения доступа к его полям ключа и значения:
для (( ключ , значение ) в карте ) println ( " $ ключ : $ значение " )
Kotlin позволяет объявлять локальные функции внутри других функций или методов.
класс Пользователь ( val id : Int , val name : String , val address : String ) забавно сохранитьUserToDb ( пользователь : Пользователь ) { забавная проверка ( пользователь : Пользователь , значение : Строка , fieldName : Строка ) { require ( value . isNotEmpty ()) { "Невозможно сохранить пользователя ${ user . id } : пусто $ fieldName " } } проверить ( пользователь , пользователь . имя , "Имя" ) проверить ( пользователь , пользователь.адрес , " Адрес " ) // Сохранить пользователя в базе данных ...}
В Kotlin, чтобы вывести новый класс из базового типа класса, базовый класс должен быть явно помечен как «открытый». Это отличается от большинства объектно-ориентированных языков, таких как Java, где классы открыты по умолчанию.
Пример базового класса, открытого для создания из него нового подкласса:
// открыто для класса означает, что этот класс будет разрешать производные классыоткрытый класс MegaButton { // no-open для функции означает, что // полиморфное поведение отключено, если функция переопределена в производном классе отключить веселье () { ... } // открытие функции означает, что // полиморфное поведение разрешено, если функция переопределена в производном классе открыть забавную анимацию () { ... } }класс GigaButton : MegaButton () { // Явное использование ключевого слова override, необходимое для переопределения функции в производном классе переопределить fun animate () { println ( "Giga Click!" ) } }
Абстрактные классы определяют абстрактные или "чисто виртуальные" функции-заполнители, которые будут определены в производном классе. Абстрактные классы открыты по умолчанию.
// Ключевое слово open здесь не нужно, по умолчанию он уже открытабстрактный класс Анимированный { // Эта виртуальная функция также уже открыта по умолчанию абстрактный веселый анимационный () открыть забавный stopAnimating () { } весело animateTwice () { } }
Kotlin предоставляет следующие ключевые слова для ограничения видимости объявлений верхнего уровня, таких как классы, и членов класса: public
, internal
, protected
, и private
.
Применительно к члену класса:
Применительно к декларации верхнего уровня:
Пример:
// Класс виден только текущему модулювнутренний открытый класс TalkativeButton { // метод виден только текущему классу личное веселье yell () = println ( "Эй!" ) // метод виден текущему классу и производным классам защищенный веселый шепот () = println ( "Давайте поговорим!" ) }внутренний класс MyTalkativeButton : TalkativeButton () { весело произносить () = супер . шепот () }MyTalkativeButton (). utter ()
Kotlin поддерживает спецификацию «первичного конструктора» как часть самого определения класса, состоящего из списка аргументов, следующего за именем класса. Этот список аргументов поддерживает расширенный синтаксис стандартных списков аргументов функций Kotlin, который позволяет объявлять свойства класса в первичном конструкторе, включая атрибуты видимости, расширяемости и изменяемости. Кроме того, при определении подкласса свойства в суперинтерфейсах и суперклассах могут быть переопределены в первичном конструкторе.
// Пример класса, использующего синтаксис первичного конструктора// (Для этого класса требуется только один конструктор)открытый класс BaseUser ( открытая переменная isSubscribed : Boolean ) открытый класс PowerUser ( защищенное значение nickname : String , окончательное переопределение var isSubscribed : Boolean = true ): BaseUser ( isSubscribed ) { }
Однако в случаях, когда для класса требуется более одного конструктора, можно определить более общий конструктор с использованием синтаксиса вторичного конструктора , который очень похож на синтаксис конструктора, используемый в большинстве объектно-ориентированных языков, таких как C++, C# и Java.
// Пример класса, использующего синтаксис вторичного конструктора// (для этого класса требуется более одного конструктора)класс Контекст класс AttributeSet открытый класс View ( ctx : Context ) { конструктор ( ctx : Context , attr : AttributeSet ): этот ( ctx ) }класс MyButton : Вид { // Конструктор №1 конструктор ( ctx : Контекст ) : супер ( ctx ) { } // Конструктор №2 конструктор ( ctx : Context , attr : AttributeSet ) : super ( ctx , attr ) { // ... }}
Запечатанные классы и интерфейсы ограничивают иерархии подклассов, что означает больший контроль над иерархией наследования.
Декларация герметичного интерфейса и класса:
герметичный интерфейс Expr запечатанный класс Работа
Все подклассы запечатанного класса определяются во время компиляции. После компиляции модуля, имеющего запечатанный класс, к нему не могут быть добавлены новые подклассы. Например, запечатанный класс в скомпилированном jar-файле не может быть подклассифицирован.
Запечатанный класс Транспортное средство класс данных Car ( val brandName : String , val owner : String , val color : String ): Vehicle () класс Велосипед ( val brandName : String , val owner : String , val color : String ): Транспортное средство () класс Трактор ( val brandName : String , val owner : String , val color : String ): Транспортное средство () val kiaCar = Автомобиль ( «KIA» , «Джон» , «Синий» ) val hyundaiCar = Автомобиль ( «Hyundai» , «Britto» , «Зеленый» )
Конструкция Kotlin data class
определяет классы, чьей основной целью является хранение данных, аналогичные типам Java . Как и типы record
Java record
, конструкция похожа на обычные классы, за исключением того, что ключевые методы equals
и автоматически генерируются из свойств класса, в отличие от записей, классы данных открыты для наследования.hashCode
toString
$ kotlinc-jvm введите :help для справки; :quit для выхода >>> 2 + 2 4 >>> println ( "Привет, мир!" ) Привет, мир!
Kotlin также может использоваться как язык сценариев. Скрипт — это исходный файл Kotlin с расширением .kts и исполняемым исходным кодом в области действия верхнего уровня:
// список_папок.ktsимпорт java.io.Файл val folders = Файл ( args [ 0 ] ) .listFiles { файл -> файл .isDirectory ( ) } папки ?. forEach ( :: println )
Скрипты можно запускать, передавая -script
опцию и соответствующий файл скрипта компилятору.
$ kotlinc -script list_folders.kts "путь_к_папке_для_проверки"
Kotlin различает типы данных, допускающие и не допускающие значение null. Все объекты, допускающие значение null, должны быть объявлены с постфиксом "?" после имени типа. Операции с объектами, допускающими значение null, требуют от разработчиков особого внимания: перед использованием значения необходимо выполнить проверку на значение null, либо явно, либо с помощью операторов Kotlin, безопасных для значений null:
// возвращает ноль, если...// - foo() возвращает ноль,// - или если foo() не равен нулю, но bar() возвращает ноль,// - или если foo() и bar() не равны нулю, но baz() возвращает ноль.// наоборот, возвращаемое значение не равно null тогда и только тогда, когда foo(), bar() и baz() не равны nullfoo () ? .bar () ? .baz ()
весело sayHello ( может быть : String? , neverNull : Int ) { // использование оператора Элвиса имя значения : Строка = может быть ?: "незнакомец" println ( "Привет, $ имя " )}
Kotlin обеспечивает поддержку функций высшего порядка и анонимных функций , или лямбда-выражений . [40]
// следующая функция принимает лямбда-функцию f и выполняет f, передавая ей строку "lambda"// обратите внимание, что (String) -> Unit указывает лямбда-выражение с параметром String и возвращаемым типом Unitfun executeLambda ( f : ( String ) -> Unit ) { ф ( "лямбда" )}
Лямбда-выражения объявляются с помощью фигурных скобок { } . Если лямбда-выражение принимает параметры, они объявляются внутри фигурных скобок и сопровождаются оператором -> .
// следующий оператор определяет лямбда-выражение, которое принимает один параметр и передает его функции printlnval l = { c : Есть? -> println ( c ) } // лямбда-выражения без параметров можно просто определить с помощью { }val l2 = { print ( "нет параметров" ) }
(Взято и объяснено по ссылке https://kotlinlang.org/docs/kotlin-tour-hello-world.html.)
весело главное () { println ( "Привет, мир!" ) // Привет, мир!}
Когда Kotlin был объявлен официальным языком разработки Android на Google I/O в мае 2017 года, он стал третьим языком, полностью поддерживаемым для Android, после Java и C++. [50] По состоянию на 2020 год [обновлять]Kotlin является наиболее широко используемым языком на Android, по оценкам Google, 70% из 1000 лучших приложений в Play Store написаны на Kotlin. У самой Google есть 60 приложений, написанных на Kotlin, включая Maps и Drive. Многие приложения Android, такие как Google Home, находятся в процессе миграции на Kotlin и, следовательно, используют как Kotlin, так и Java. Kotlin на Android считается полезным из-за его безопасности нулевого указателя , а также из-за его функций, которые делают код более коротким и читаемым. [51]
В дополнение к своему заметному использованию на Android, Kotlin набирает обороты в серверной разработке. Spring Framework официально добавил поддержку Kotlin с версии 5 4 января 2017 года. [52] Для дальнейшей поддержки Kotlin Spring перевел всю свою документацию на Kotlin и добавил встроенную поддержку многих специфичных для Kotlin функций, таких как сопрограммы. [53] В дополнение к Spring, JetBrains выпустил Kotlin-first фреймворк под названием Ktor для создания веб-приложений. [54]
В 2020 году JetBrains обнаружила в ходе опроса разработчиков, использующих Kotlin, что 56% использовали Kotlin для мобильных приложений, а 47% — для веб-бэкенда. Чуть более трети всех разработчиков Kotlin заявили, что переходят на Kotlin с другого языка. Большинство пользователей Kotlin ориентировались на Android (или иную платформу JVM), и только 6% использовали Kotlin Native. [55]
В 2018 году Kotlin был самым быстрорастущим языком на GitHub, с числом разработчиков, выросшим в 2,6 раза по сравнению с 2017 годом. [56] Это четвертый по популярности язык программирования по данным опроса разработчиков Stack Overflow 2020 года. [57]
Kotlin также был удостоен награды O'Reilly Open Source Software Conference Breakout Award за 2019 год. [58]
Многие компании/организации использовали Kotlin для бэкэнд-разработки:
Некоторые компании/организации использовали Kotlin для веб-разработки:
Ряд компаний публично заявили об использовании Kotlin:
позволяет вам выбрать версию JVM для выполнения. По умолчанию компилятор Kotlin/JVM создает байт-код, совместимый с Java 8. Если вы хотите использовать оптимизации, доступные в более новых версиях Java, вы можете явно указать целевую версию Java от 9 до 21. Обратите внимание, что в этом случае полученный байт-код может не работать на более ранних версиях.
ожидаем, что Kotlin будет стимулировать продажи IntelliJ IDEA
Сегодня на конференции Google I/O команда Android объявила о первоклассной поддержке Kotlin.
на всех платформах является явной целью Kotlin, но мы рассматриваем это как предпосылку для гораздо более важной цели: совместного использования кода между платформами. Благодаря поддержке JVM, Android, JavaScript, iOS, Linux, Windows, Mac и даже встроенных систем, таких как STM32, Kotlin может обрабатывать любые и все компоненты современного приложения.
версии 1.4.0 мы немного изменяем API Swift, сгенерированный из Kotlin, в отношении способа перевода исключений.
Реализовать полную семантику Eiffel DbC и улучшить ее.