Comments 31
А где, простите, преимущества? Где недостатки?
Преимущества и недостатки предполагают какое-то сравнение: "здесь сделано так, поэтому в сравнении с X это преимущество, а вот здесь так, поэтому в сравнении с Y это недостаток"
Вы же, по большому счету, просто перепечатали фрагмент документации языка.
Ну кто в студию Чулакова на Android developer собеситься будет, будет в курсе что там спрашивают :)
Можно сказать, что первые 15-20 минут о чем поговорить будет.
Статья посвящена не только преимуществам и недостаткам языка, в ней рассказывается про базовые концепции Kotlin, из которых и вытекают плюсы и минусы.
Они прослеживаются по мере разбора отдельных тем. Например, в блоках про null safety мы выделили плюс — избежание NullPointerException. В блоке про lateInit мы рассказали про минус этого инструмента, а также что привело к его добавлению.
Глазами дотнетчика со стажем, "типы" Any, Unit, Nothing выглядят однозначно как костыли и подпорки. Дата-классы без наследования? Печаль :( Целое ключевое слово sealed там, где просто можно сделать приватный конструктор? Why? Обычный декоратор почему-то называется делегатом да ещё и синтаксис придумали, в котором в общем-то нет нужды, только если вся платформа не построена на декорировании. Целый ворох других точечных ключевых слов, которые особо-то и не нужны. К сожалению, так и не смог разделить восторга, ну разве что если с Java сравнивать.
В сравнении с чистой Java, особенно до 17 версии, котлин на голову выше.
Что касается sealed классов, основное назначение - это ограничить число наследников. Боюсь только приватным конструктором это не решить.
Все ж это не про ограничение, а про знание всех потомков на этапе компиляции (else не нужен, если все обработаны). В количестве то никто не ограничивает.
Как раз ограничить число наследников приватным конструктором можно: их либо вообще не будет, либо это будут классы, вложенные в родительский. Вот только это может привести к тонне кода в одном классе, что как бы не есть хорошо.
По поводу data-классов без наследования: Kotlin активно использует композицию вместо наследования, что способствует более гибкой и расширяемой архитектуре. Data-классы не наследуются, чтобы избежать потенциальных проблем, связанных с этим.
По поводу сравнения с Java: вы правы. Kotlin является оберткой для Javа. Компания Jetbrains поставила перед собой цель — создание нового языка программирования, который был бы лучше, чем Java, но все еще функционально совместим с ним. На наш взгляд, у них это получилось.
Во-первых, Котлин умеет компиляцию (транспиляцию) в JavaScript
Во-вторых, Котлин умеет компиляцию даже в native
В-третьих, у Андроида, насколько я знаю, своя VM, несовместимая с JVM
И в четвертых, а почему JVM под капотом означает что мы кого-то обманываем? Кроме Java на JVM работают многие другие языки - Scala, Groovy, JRuby и т.д. Точно также как на платформе .net существует не только C#, но и другие языки.
Кажется в моменте когда технологии уже почти 5 лет, пора остановиться в разборах плюсов и минусов
Одно из ключевых преимуществ Kotlin — это его поддержка null safety
Как считаете, у них это получилось? В яве равн нулл, не равно нулл, ну потом еще Optional придумали. Тут стало в 2 раза больше типов с вопросом и без, добавились команды "?.", "?:", "!!", потом выяснилось, что объект, который объявлен как не могущий быть null, непонятно чем инициализировать и ввели lateinit, ну и дальше насыпали методов вроде orNull(). Ну а в коде для полей с вопросом дополнительно вызывается проверка на null с бросанием NullPointerException, которое бы выбросилось бы и так при попытке доступа.
Давайте обсудим в комментариях перспективы языка Kotlin в контексте мобильной разработки
Компилируется долго почему-то.
По скорости компиляции уже много раз сравнивали - Java компилируется быстрее только на этапе clean build. И то, разница что-то около 10%. Если сравнивать по incremental build (а в основном так и билдят), то Kotlin компилится уже немножечко быстрее чем Java.
Вот время компиляции одного и того же небольшого приложения в 2-х версиях на моём компьютере, несколько последовательных прогонов:
Kotlin:
BUILD SUCCESSFUL in 2m 24s
BUILD SUCCESSFUL in 1m 51s
BUILD SUCCESSFUL in 1m 2s
BUILD SUCCESSFUL in 1m 37s
BUILD SUCCESSFUL in 1m 25s
Java:
BUILD SUCCESSFUL in 1m 30s
BUILD SUCCESSFUL in 44s
BUILD SUCCESSFUL in 38s
BUILD SUCCESSFUL in 32s
BUILD SUCCESSFUL in 29s
Не похоже на 10%.
У меня периодически инкрементальная сборка увеличивает размер выходного файла. как у вас?
Так это, я подозреваю вовсе даже не incremental build. Инкрементный - это когда вносятся изменения в несколько файлов исходного кода и затем компилятор пересобирает только их. А у вас, скорее всего, данные легли в какой-то кэш, за счет этого сокращение времени компиляции.
Это результаты прогонов последовательных "холодных" сборок. Время изменяется из-за прогрева кэша.
Что насчёт увеличения размера файла при инкрементальной сборке относительно сборки с нуля?
Не забываем, что lateinit - потенциальная дыра в работе с такой переменной (привет доп. проверки при помощи "::isInitialized")
Если вам нужно проверять lateinit с помощью isInitialized - вы что-то делаете неправильно. Вероятно эта переменная должна быть у вас nullable.
lateinit нужен когда мы не можем задать значение переменной в момент её объявления, но гарантированно зададим к моменту её первого использования (а если не зададим - то получим эксепшен).
Nothing - это не специальный тип, а класс.
на мой взгляд, Scala как-то попонятнее. Единственное, что в котлине сделано лучше, чем в Scala - корутины на уровне языка, тогда как в Scala - на уровне библиотеки (cats-effect|zio| ... + cps)
Автор статьи хотя бы пробовал проверять тот код который он написал?
nullableString?.let { str ->
// Блок кода, который должен выполниться, если nullableString не равен null
val length: Int = str.length
} ?: {
// Блок кода, который будет выполнен, если nullableString равен null
println("nullableString равен null")
}
Блок кода с // Блок кода, который будет выполнен, если nullableString равен null
на самом деле выполнен не будет, тут забыли добавить run
Автор проверял, но опечатки случаются со всеми) Спасибо, что внимательно прочитали статью. Вот работающий код:
nullableString?.let { str ->
// Блок кода, который должен выполниться, если nullableString не равен null
val length: Int = str.length
} ?: run {
// Блок кода, который будет выполнен, если nullableString равен null
println("nullableString равен null")
}
Kotlin: взгляд изнутри — преимущества, недостатки и особенности