company_banner

Вышел Kotlin M5

    Скоро год как мы открыли исходный код Kotlin. За это время проделана большая работа, в которой активно участвовали как разработчики из JetBrains, так и представители комьюнити. Нам пришло 164 pull requests, то есть что-то около одного патча каждые два дня.

    Сегодня мы выпустили очередной milestone: Kotlin M5. Этот пост дает краткое описание изменений, вошедших в M5.

    Конструкторы по умолчанию



    Класс, написанный на Kotlin может иметь только один конструктор. Перегружать конструкторы незачем, поскольку есть значения по умолчанию для параметров:

    class Foo(val bar: Int = 0)
    


    Однако многие Java-фреймворки, например, JAXB, требуют, чтобы у класса был конструктор по умолчанию, то есть без параметров. Теперь Kotlin генерирует такой конструктор, если все параметры могут быть опущены.

    Inner-Классы



    Начиная с M5, Kotlin поддерживает не только inner-классы, но и «статические» nested-классы. Поскольку объект inner-класса хранит ссылку на объект объемлющего класса, что может приводить к неожиданным последствиям (например, к утечкам памяти), Kotlin требует явно помечать inner-классы соответствующей аннотацией:

    class Outer {
      val foo = 1
      inner class Inner {
        val bar = foo + 1
       }
    }
    


    Generics, Nullability, Assertions



    Kotlin различает nullable и not-null ссылки на уровне системы типов. Поскольку в Java для ссылок нет никаких гарантий того, что они не равны null, Kotlin загружает все непримитивные типы как nullable. Например, Java-метод foo(ArrayList) из Kotlin виден как foo(ArrayList<String?>?), то есть как сам список может быть null, так и любой его элемент. Этот подход наиболее безопасен, однако с ним возникает такая проблема: если где-то в Kotlin у меня уже есть ArrayList, я не могу передать его методу foo(), потому что класс ArrayList ивариантен, и типы не сходятся. Эта проблема сильно мешает жить, поэтому мы пошли на компромисс: теперь Kotlin не делает аргументы generic-типов nullable, то есть foo() будет загружен как
    foo(ArrayList?) и передать туда список обычных строк будет можно.

    Теперь из Java-кода легче "сломать" программу на Kotlin, вызвав NPE, однако компилятор Kotlin делает все возможное, чтобы такие ошибки было легко искать: в байт-код вставляются соответствующие проверки, и некорректное значение будет обнаружено как только оно попадет из Java-кода в Kotlin-код:

    Exception in thread "main" java.lang.IllegalStateException: Method specified as non-null returned null: JavaClass.foo at _DefaultPackage.main(hello.kt:4)


    Заключение


    Kotlin M5 можно скачать из репозитория плагинов, рекомендуется использовать недавно вышедшую IntelliJ IDEA 12.0.3.

    Кроме описанного здесь, случилось еще много чего: от поддержки цветовой схемы Darcula до возможности смешивать именованные и позиционные параметры функций. Более подробно про M5 можно почитать здесь (по-английски). Приятного Котлина!
    JetBrains
    177.41
    Делаем эффективные инструменты для разработчиков
    Share post

    Comments 14

      +1
      а чем закончилась история с письмами к Санта-Клаусу? blog.jetbrains.com/blog/2012/12/18/santa-service-at-jetbrains/
        +1
        Здесь писали, чем история закончилась.
          0
          спасибо, пропустил. видать не очень был искренним :)
        +1
        Перегружать конструкторы незачем

        Да? «Вы неправильно его держите»? А если надо? Если надо по-разному сконструировать в зависимости от типа первого аргумента.
          0
          Можно делать вот такой финт ушами:

          class Greeter(val name : String) {
            fun greet() = println("Hello, ${name}")
          }
          
          fun Greeter(val value:Int) = Greeter(value.toString())
          
          fun main(args : Array<String>) {
            Greeter(1).greet()
          }
          
            0
            А вы уверены, что надо? По описанию похоже на два разных класса с общим родителем!
              +2
              НЛО прилетело и напомнило что make-функции всё ещё доступны человечеству.
              0
              Перегружать конструкторы незачем

              А как без перегрузки конструктора сделать что-то вроде:
              class A {
              	private readonly B _b;
              	private readonly C _c;
              	A(B b) {
              		_b = b;
              		_c = f1(b);
              	}
              	
              	A(C c) {
              		_c = c;
              		_b = f2(c);
              	}
              }
              

              ?

              Если мы сделаем конструктор:
              A(B b = null, C c = null) {
              	...
              }
              

              то из него не будет понятно, что надо обязательно указать по крайней мере один(или вообще только один) из параметров.
                +1
                Думаю как то так:

                class A(val b: B, val c: C);
                
                fun A(b: B) = A(b, f1(b));
                
                fun A(c: C) = A(f2(c), c);
                


                А еще лучше написать так:
                data class A(val b: B, val c: C);
                

                и тогда компилятор сгенерирует toString(), equals(), hashCode() и функции для доступа к компонентам класса, чтобы можно было писать так:
                val (b, c) = funWhichReturnsA()
                

                  0
                  Остроумно, не удобно импортировать.

                  Думал можно по аналогии со scala воспользоваться class object с методом invoke — не работает даже если явно унаследовать class object от jet.Function1. Кстати, не понятно почему.
                    0
                    А в чем неудобства с импортом?
                      0
                      Ошибся: функция может быть объявлена прямо в пакете.
                –2
                Я вот читаю новости про новый язык и думаю: с одной стороны, как Java-разработчик, я вас поддерживаю — самого раздражают многие ограничения Java. С другой стороны — разве все баги в IDEA уже пофикшены? И возникает возмущение — как же так, не могут пофиксить давний баг, который лично мне мешает, но при этом тратят силы на еще один язык.

                Scala придумали в 2003, и до сих пор в компиляторе находят баги. Некоторые баги в IDEA живут годами. Отсюда делается вывод, что баги в Kotlin тоже будут жить годами. А ведь баг в языке гораздо серьезней бага в IDE.
                  0
                  Kotlin позиционировался как средства дальнейшей разработки IDEA.
                  Если он повысит эффективность разработки, то повысится и скорость исправления багов в IDEA.

                  Это как утверждать, что рефакторинг вреден, так как вместо него можно было бы фиксить баги.

                  Кстати, баги в компиляторе scala довольно не критичны. Да, на них можно наткнуться, но не то, чтобы просто.

                Only users with full accounts can post comments. Log in, please.