При разработке библиотек на Kotlin одним из элегантных решений является подход, знакомый многим по Flow из Coroutines. Его суть в том, что интерфейс содержит только базовый, фундаментальный метод, а все остальные операторы реализованы как функции-расширения.
Например, интерфейс Flow из Kotlin выглядит так:
interface Flow<out T> {
suspend fun collect(collector: FlowCollector<T>)
}
fun interface FlowCollector<in T> {
suspend fun emit(value: T)
}
Почему это хороший подход?
👉 Минимализм и ясность интерфейса. Один метод в интерфейсе ясно показывает суть контракта, облегчает понимание и поддержку.
👉 Гибкость расширения API. Можно добавлять бесконечное количество новых операторов без изменения интерфейса и нарушения обратной совместимости.
👉 Удобство и читаемость. Цепочки вызовов выглядят компактно, легко читаемы и следуют единому стилю, принятому в Kotlin.
Плюсы подхода
✅ Простое масштабирование библиотеки, благодаря гибкости Kotlin Extension-функций.
✅ Лёгкость в написании и поддержке тестов, так как расширения можно тестировать отдельно.
✅ Улучшение читаемости клиентского кода благодаря последовательной и понятной структуре вызовов.
✅ Простые и понятные API интерфейсов в типах
Минусы подхода
⚠️ Сложность в управлении видимостью и областью применения расширений. Пользователь может запутаться в большом количестве операторов.
⚠️ Ограничение на возможность переопределения методов. Расширения не переопределяются, что может осложнить кастомизацию.
Когда лучше использовать методы интерфейса вместо расширений?
Обычно в интерфейс стоит помещать:
👉 Фундаментальные методы, которые описывают самую суть интерфейса.
👉 Методы, для которых критично переопределение и которые могут требовать разных реализаций в разных имплементациях.
👉 Функции, критичные к производительности, так как их реализация через расширения иногда менее эффективна.
Когда методы стоит делать как расширения
Явными кандидатами для функций через расширения к интерфейсу - те что имеют реализацию по умолчанию и просто вызывают другие функции этого же интерфейса
interface Container {
val childCount: Int
// ❌ Не имеет смысла как функция интерфейса
fun isEmpty(): Boolean = childCount == 0
}
// ✅ Дополнительное расширение, которое не нужно как часть API интерфейса
fun Container.isEmpty(): Boolean = childCount == 0
💬 Делитесь в комментариях используете ли вы такой подход при проектирование API
#kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
3🤔24👍17👎3
Ключевые приоритеты разработки:
👉 Развитие возможностей языка: более высокие абстракции, лучшая производительность, более чистый код, повышение эффективности обработки данных.
👉 Kotlin Multiplatform: релиз "Kotlin to Swift Export", упрощение настройки проектов и создание KMP библиотек.
👉 Улучшение опыта сторонних контрибьюторов в экосистеме Kotlin.
#kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40
Что нового в Kotlin за последние полгода?
👉 Поддержка отладки inline-функций в Android на уровне компилятора Kotlin
👉 Поддержка XCode 16 для KMP
👉 Публичная документация по API Kotlin Gradle Plugin
👉 Рабочая из коробки отладка для Kotlin/WASM
👉 Новое KMP API для Atomic
👉 Новые руководства для авторов библиотек
#kotlin
👉 Поддержка отладки inline-функций в Android на уровне компилятора Kotlin
👉 Поддержка XCode 16 для KMP
👉 Публичная документация по API Kotlin Gradle Plugin
👉 Рабочая из коробки отладка для Kotlin/WASM
👉 Новое KMP API для Atomic
👉 Новые руководства для авторов библиотек
#kotlin
👍19
🆕 Финализация поддержки JSpecify (подробности здесь)
🆕 Завершение поддержки компилятора K1. Переносится в категорию "Deprecated"
🆕 Перевод Kotlin/Wasm (wasm-js) в Beta
Kotlin/Wasm:
⛏️ Переключение таргета wasm-wasi в библиотеках на WASI Preview 2
⛏️ Поддержка компонентной модели
#kotlin #wasm #k1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20
В ближайшие полгода в Kotlin Multiplatform будет много интересного:
👉 Первый публичный релиз прямого экспорта Kotlin в Swift (возможно, сторонние плагины для этого больше не понадобятся).
👉 Включение по умолчанию Concurrent Mark and Sweep (CMS) GC (быстрее и эффективнее).
👉 Реализация нового поколения формата распространения KMP библиотек (упрощение формата в фокусе).
🔥 Возможность объявлять зависимости KMP проектов в блоке dependency на уровне проекта, а не в DSL Kotlin плагина.
👉 Унификация работы inline функций между всеми стабильными таргетами (сейчас есть отличия в JVM).
👉 Включение инкрементальной компиляции klib артефактов по умолчанию.
👉 Стабилизация кросс-компиляции klib на разных платформах, что улучшит опыт разработчиков, работающих не на Mac.
У KMP даже есть свой дорожная карта разработки.
#kotlin #kmp
👉 Первый публичный релиз прямого экспорта Kotlin в Swift (возможно, сторонние плагины для этого больше не понадобятся).
👉 Включение по умолчанию Concurrent Mark and Sweep (CMS) GC (быстрее и эффективнее).
👉 Реализация нового поколения формата распространения KMP библиотек (упрощение формата в фокусе).
🔥 Возможность объявлять зависимости KMP проектов в блоке dependency на уровне проекта, а не в DSL Kotlin плагина.
👉 Унификация работы inline функций между всеми стабильными таргетами (сейчас есть отличия в JVM).
👉 Включение инкрементальной компиляции klib артефактов по умолчанию.
👉 Стабилизация кросс-компиляции klib на разных платформах, что улучшит опыт разработчиков, работающих не на Mac.
У KMP даже есть свой дорожная карта разработки.
#kotlin #kmp
👍24
👉 Поддержка Gradle Project Isolation (подробнее об этой функции здесь)
👉 Улучшение отчетов по компиляции Kotlin
👉 Поддержка Declarative Gradle
👉 Улучшение интеграции инструментов Kotlin/Native в Gradle
👉 Выпуск стабильных аргументов компилятора в Gradle DSL для упрощения конфигурации проектов на Kotlin и KMP
#kotlin #gradle
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22
Для каких задач вы используете Kotlin?
Anonymous Poll
79%
Разработка только под Android
22%
Разработка Backend системы
4%
Разработка только под Desktop
31%
Разработка под несколько платформ на KMP
10%
Написание скриптов (не Gradle KTS)
2%
Другое применение (делитесь в комментариях)
2%
Не пишу на Kotlin
4%
Не участвую в опросе
3👍8
Совсем недавно наткнулся на полную официальную доку по API Gradle плагина Kotlin Multiplatform
#kotlin #kmp #документация
#kotlin #kmp #документация
👍34
JetBrains представила новую версию языка программирования Kotlin 2.1.20. В этом обновлении:
👉 Новый плагин компилятора kapt на основе K2 по умолчанию (обещают ускорение работы)
🧪 Kotlin Multiplatform: Новый DSL для замены плагина Application в мультиплатформенных проектах.
🧪 Kotlin/Native: Оптимизация инлайнинга для повышения производительности (нужно включение через опцию компилятора)
👉 Kotlin/Wasm: Пользовательские форматтеры теперь включены по умолчанию в дев сборках.
👉 Стандартная библиотека: Введение common атомарных типов, улучшенная поддержка UUID и новая функциональность для отслеживания времени.
#kotlin #kmp #k2
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26
Новое DSL на замену Gradle Application плагина
В Kotlin 2.1.20 появилось новое экспериментальное DSL для замены функций Gradle Application плагин (несовместим с KMP Gradle плагин, начиная с Gradle 8.7)
#kotlin #gradle #kmp
В Kotlin 2.1.20 появилось новое экспериментальное DSL для замены функций Gradle Application плагин (несовместим с KMP Gradle плагин, начиная с Gradle 8.7)
kotlin {
jvm {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
binaries {
// Configures a JavaExec task named "runJvm"
// and a Gradle distribution for the "main" compilation in this target
executable {
mainClass.set("foo.MainKt")
}
// Configures a JavaExec task named "runJvmAnother"
// and a Gradle distribution for the "main" compilation
executable(KotlinCompilation.MAIN_COMPILATION_NAME, "another") {
// Set a different class
mainClass.set("foo.MainAnotherKt")
}
// Configures a JavaExec task named "runJvmTest"
// and a Gradle distribution for the "test" compilation
executable(KotlinCompilation.TEST_COMPILATION_NAME) {
mainClass.set("foo.MainTestKt")
}
// Configures a JavaExec task named "runJvmTestAnother"
// and a Gradle distribution for the "test" compilation
executable(KotlinCompilation.TEST_COMPILATION_NAME, "another") {
mainClass.set("foo.MainAnotherTestKt")
}
}
}
}
#kotlin #gradle #kmp
👍15
Пример работы нового Common Atomic API из Kotlin 2.1.20
#kotlin
@OptIn(ExperimentalAtomicApi::class)
suspend fun main() {
// Initializes the atomic counter for processed items
var processedItems = AtomicInt(0)
val totalItems = 100
val items = List(totalItems) { "item$it" }
// Splits the items into chunks for processing by multiple coroutines
val chunkSize = 20
val itemChunks = items.chunked(chunkSize)
coroutineScope {
for (chunk in itemChunks) {
launch {
for (item in chunk) {
println("Processing $item in thread ${Thread.currentThread()}")
processedItems += 1 // Increment counter atomically
}
}
}
}
#kotlin
👍33
Что нового в UUID из Kotlin Standart Library
🏝 Теперь функция Uuid.parse() поддерживает не только привычный формат с дефисами (hex-and-dash), например,
🏝 Появились явные функции для работы с hex-and-dash форматом:
parseHexDash() – парсинг UUID из формата с дефисами.
toHexDashString() – преобразование UUID в строку с дефисами.
🏝 UUID теперь реализует интерфейс Comparable. Это значит, что UUID можно напрямую сравнивать и сортировать, используя операторы <, > и стандартные функции вроде sorted().
⚠️ Не забывайте, поддержка UUID в стандартной библиотеке пока экспериментальная. Для её использования используйте:
#kotlin
UUID (Universally Unique Identifier) – это стандарт для генерации уникальных идентификаторов длиной 128 бит, который широко используется для идентификации объектов в распределенных системах.
550e8400-e29b-41d4-a716-446655440000
, но и простой шестнадцатеричный формат без дефисов, например, 550e8400e29b41d4a716446655440000
.parseHexDash() – парсинг UUID из формата с дефисами.
toHexDashString() – преобразование UUID в строку с дефисами.
⚠️ Не забывайте, поддержка UUID в стандартной библиотеке пока экспериментальная. Для её использования используйте:
@OptIn(ExperimentalUuidApi::class)
fun main() {
val uuid = Uuid.parse("550e8400e29b41d4a716446655440000")
println(uuid.toHexDashString())
val sortedUuids = listOf(
uuid,
Uuid.parse("780e8400e29b41d4a716446655440005"),
Uuid.parse("5ab88400e29b41d4a716446655440076")
).sorted()
println(sortedUuids)
}
#kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53
// Kotlin Common Code
expect fun openInBrowser(
url: String,
completionHandler: (Boolean) -> Unit = {}
)
// Kotlin iOS Common
actual fun openInBrowser(
url: String,
completionHandler: (Boolean) -> Unit
) {
NSURL.URLWithString(url)?.let {
UIApplication.sharedApplication.openURL(
url = it,
options = emptyMap<Any?, Any>(),
completionHandler = completionHandler
)
}
}
actual fun openInBrowser(
url: String,
completionHandler: (Boolean) -> Unit
) {
val result = try {
context.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(url))
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
true
} catch (_: ActivityNotFoundException) {
false
}
completionHandler(result)
}
// Kotlin JVM Desktop Common
actual fun openInBrowser(
url: String,
completionHandler: (Boolean) -> Unit
) {
with(Desktop.getDesktop()) {
val result = if (isSupported(Desktop.Action.BROWSE)) {
try {
browse(URI.create(url))
true
} catch (e: IOException) {
false
} catch (e: SecurityException) {
false
}
} else false
completionHandler(result)
}
}
Источник тут
#kmp #kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40
В Kotlin проекте для генерации кода у вас используется...
Anonymous Poll
9%
Нету кодогенерации
28%
KAPT
59%
KSP
8%
Плагин Kotlin компилятора
11%
Генерация через Gradle плагин
2%
Другой способ генерации
7%
Не знаю
9%
Не участвую в опросе
👍3
Вышла KotlinX Serialization 1.8.1 с исправлениями багов и минорными улучшениями. Также обновили Kotlin до 2.1.20
#kotlin
#kotlin
👍17
#kotlin #di #koin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Media is too big
VIEW IN TELEGRAM
Хотите узнать, как использовать платформозависимые API в своих приложениях Kotlin Multiplatform (KMP) или запутались в связанных с этим лучших практиках?
В этом видео мы расскажует об использования механизма expect/actual для создания отличных приложений на KMP.
#kmp #kotlin #jetbrains
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10