Comments 13
Преимущества языка Kotlin перед Java
Функции высшего порядка и Лямбда-выражения
Сомнительное преимущество - в Java ещё с восьмой версии лямбды есть так-то
Про корутины написано как-то сумбурно:
Сначала говорите, что потоки создавать можно, а в следующем абзаце - что андроид однопоточный.
Ну и главный поток блокируется не потому, что на процессор большая нагрузка - какая нагрузка от запроса по сети?
Спасибо автору за очень полезную систематизацию базовых понятий Котлина.
Добавлю немного от себя.
Синглтон-свойство
companion object
достигается за счет того, что он создается внутри класса в качестве статического поля и инициализируется один раз при первом обращении к нему.
Он инициализируется не только при первом обращении к нему, но так же при создании первого экземпляра того класса MyClass, в котором объявлен. При этом важно, что Companion Object будет инициализирован первым, а уже затем будет инициализирован экземпляр самого класса:
MyClass {
init {
...
}
companion object {
init {
// Выполняется всегда до блока init содержащего класса
}
}
}
val myclass = MyClass()
Вот чем меня Котлин отпугивает, так это необходимостью знать Джаву. Вроде бы ответы статья про Котлин, а Java упоминается 49 раз.
Мне кажется, что было бы сложно написать статью про язык на платформе JVM, при этом ни разу не упомянув Java)
Не переживайте, это первая часть вопросов, где идет сравнение с Java, в следующих частях будет не так часто встречаться.
Если знаете С++, то никаких проблем не будет тоже
Kotlin может компилироваться не только в байткод Java, но еще и в JavaScript ;-)
Хорошая статья. Начал переходить с java на kotlin, после того, как ИИ посоветовал всё-таки использовать kotlin вместо java. ИИ очень помогает составлять код, да и есть автоматическое форматирование кода в kotlin из AS. Стал нравится больше чем java.
Много что в статье очень полезно
Про Nothing написан какой-то "немножко сумбур".
Nothing является типом, который полезен при объявлении функции, которая ничего не возвращает и не завершается.
Nothing - это т.н.bottom type. Т.е. - ко всему прочему - он является подтипом любого другого. Собственно, именно этим он и "полезен", как вы выражаетесь. Его наличие в системе типов позволяет типизировано выражать то, что без него принципиально не возможно.
Если возвращаться к "каноническим" примерам... например с ф-цией TODO(): Nothing, то именно то, что она вычисляется в Nothing (т.е. в bottom type) и дает возможность делать такое:
val x: String = TODO()
val y: Int? = TODO()
// и т.д.
Но вся прелесть наличия bottom type раскрывается в параметризированных типах и их ковариантности.
Ну и с "аналогами в java" - не то, что не верно... но, не совсем полно, что ли.
Действительно, каждый ссылочный тип Java, включая java.lang.Void, принимает в качестве значения null, а Nothing не принимает даже этого.
Если немножко задуматься о том, какого типа в java null, то можно весьма быстро выяснить, что в java таки тоже есть свой bottom type. Проблема с ним только одна: тип-то есть, а имени у него нет. Т.е. - буквально - аналог-то есть, но использовать его нельзя :-)
Большое спасибо за такое подробное уточнение.
Решил добавить отдельный вопрос про подтип всех типов в Kotlin.
Насчет аналога Nothing в Java - спасибо за ссылку на документацию, полезная информация. Изначально данный цикл задумывался как короткие ответы на вопросы для собеседований, но постепенно стал добавлять и более подробные объяснения с примерами кода. К сожалению, абсолютно все ответы глубоко расписывать нет возможности (иначе закопаемся в байт-коде и копировании документации), но, в случае грамотных дополнений в комментариях к посту, я исправляю/уточняю свои ответы.
И снова про корутины. Глаз царапнуло.
1) У них нет мистической возможности не блочить тред для тяжелых вычислений. И это вообще не задача асинка которую решают корутины.
2) Корутина сама по себе (не касаясь структурной конкурентности) не дает вообще ничего принципиально иного нежели коллбек. Который мы используем чтобы не блочить текущий тред для ожидания вычисления или IO от другого треда. Корутина делает его удобным.
3) Саспенд сам по себе это коллбек через каждую строчку (для стейтмашины в диспетчере)
4) Чтобы сделать что-то асинхронно надо заявить это явно (async или launch), в отличие например от js|dart где async-функции порождают Future, которую можно забыть await, так что асинхронный код именно что отличается от синхронного
5) За счет стейтмашины то время пока мы что-то там await в саспенд функции - диспетчер может заняться другими задачами которые ему направлены - и вот это вот основная вкусность когда нам надо написать синхронный, но неблокирующий код. Пока корутина что-то ждет - она в принципе остановлена.
6) Со звездочкой. У Елизарова в одном из докладов звучит мысль о том что в саспенде нельзя совершать длительных операций блокирующих тред. Не "нельзя технически", а скажем так это нарушает явность происходящего. То есть IO-операции и вычисления мы заявляем в обычных функциях. Они не менеджерятся диспатчерами и на них не порождается континуаций. Мы про них сразу понимаем что они займут тред ровно настолько насколько будут выполняться. Их мы можем вызвать внутри саспенда через async|launch над другим контекстом с другим диспетчером, что направит их в нужный для их выполнения тредпул, а нам отдаст управляемый уже в нашем саспенде deferred|job.
Они не могли придумать просто `static {}` вместо `companion object {}`?
Все таки эта штука имеет связь с Java.
Вопросы и ответы для собеседования по Kotlin. Часть 1