Вышел Kotlin M4, очередной milestone нашего языка программирования. Теперь Kotlin совместим с JDK7, научился еще лучше выводить типы, стал побыстрее. Сильно продвинулся отладчик, интеграция IDE с JUnit, поддержан новый механизм сборки, который со временем перерастет в инкрементальный компилятор… В этом посте я коротко расскажу о самом интересном, более подробно про M4 можно почитать здесь (по-английски).
KAnnotator
Как вы, наверное, помните, система типов Kotlin несколько богаче той, что есть в Java. В частности, Kotlin контролирует нулевые ссылки на уровне системы типов. Это прекрасно работает, пока не возникает необходимость взаимодействовать в Java-кодом, в котором нигде не написно, что может быть null, а что нет, и компилятору Kotlin приходится предполагать худшее: что все-все-все может быть null. Этот подход — безопасный, но не очень удобный, поэтому в предыдущем релизе, Kotlin M3, мы поддержали механизм внешних аннотаций, который позволяет пользователю объяснить среде, что тот или иной метод никогда не возвращает null (на самом деле, можно сообщить среде гораздо больше, но об этом в другой раз).
Кстати, эти аннотации полезны не только для Kotlin, в IntelliJ IDEA есть замечательные инспекции, помогающие избегать NPE в Java, мы в JetBrains ими постоянно пользуемся, и очень довольны.
Однако аннотировать большие библиотеки вручную — трудно, да и по их коду не всегда понятно, какие аннотации нужно указывать. Поэтому мы разработали специальный инструмент (написанный, конечно, на Kotlin) — KAnnotator, который читает байт-код библиотек и автоматически выводит нужные аннотации. Работает это примерно так: на вход поступает набор jar-файлов, KAnnotator их анализирует, и выдает xml-файлы, содержащие аннотации в примерно таком виде:
Эти аннотации можно подключить к своему проекту, и как IDE, так и компилятор Kotlin будут их видеть.
KAnnotator еще очень молод, он будет развиваться и умнеть, но уже сегодня у нас есть автоматически проаннотированная версия JDK, которая входит в M4.
Копирование для Data Classes
В M3 появились data classes (классы данных), и многие пользователи просили поддержать возможность копировать объекты этих классов, заменяя значения некоторых полей (сами объекты часто являются неизменяемыми). В M4 такая возможность поддерживается:
data class Person(val firstName: String, val lastName: String)
fun Person.asMarried(newLastName: String)
= this.copy(lastName = newLastName)
Функция copy() автоматически генерируется для всех классов данных, каждый ее параметр имеет значение по умолчанию, поэтому при копировании достаточно указывать только те свойства, значения которых изменяются.
Вариантность в Java
Generic-классы в Kotlin позволяют указывать вариантность типовых параметров, а в библиотеке коллекций есть интерфейсы только для чтения, которые указывают вариантность правильно, поэтому List<String>
можно передать туда, где ожидается List<Any>
. Если Вы пишете на Kotlin. А если на Java?
Начиная с M4, Kotlin генерирует байт-код, который позволяет пользоваться вариантностью даже из Java. Например, такая функция:
fun join(l: List<Any>, separator: String): String = ...
транслируется в метод с таким заголовком:
String join(List<? extends Object>, String separator)
Соответственно, даже из Java в него можно передать List<String>
, и это будет правильно работать.
И многое другое...
Произошло еще несколько интересных вещей, например, на главной странице появился поиск, агрегирующий все ресурсы по Kotlin, а в компиляторе улучшилась диагностика… Об этом и о многом другом читайте в нашем блоге.
Новый плагин требует IntelliJ IDEA 12, которая вышла в релиз на днях, скачать ее можно здесь (доступна бесплатная версия Community Edition). Инструкция по установке здесь.
Приятного Котлина!
Автор: abreslav