(пока) Я не отвечаю за то что вам захочется попробовать Так же как и за то, что вам не захочется Я знаю не всё, а значит могу ошибаться или неправильно понимать то, что другие люди понимают правильно или просто там не ошибаются. Но я стараюсь
10 лет в разработке Почти всё время — на JVM Учусь по референсам и на ошибках Экспериментирую Попробовал всякое от Java до Ceylon и Frege module Hello where greeting friend = "Hello, " ++ friend ++ "!" main args = do println (greeting "World")
Много сущностей, которые меняются Надоел бойлерплейт и костыли @Getter @Setter @EqualsAndHashCode @AllArgsConstructor @RequiredArgsConstructor public class Person{ //… data class Person( //… VS Код здорового разработчика тут Да, мы знали про @Data
хорошую совместимость с Java Идеальное делегирование Нормальный вызов функций без всякого apply() extension-методы fun Iterable<Int>.sum() = reduce{a, b → a + b} Это уже есть в стандартной библиотеке
repo2: Repository2) { fun complex(datum: String): Result { val interim = repo1.save(datum) return repo2.destroy(someOp(interim)) } private fun someOp(input: String) = if (notLucky(input)) throw Exception("Sorry, bro") else input Что может пойти не так?
Repository1, repo2: Repository2) { open fun complex(datum: String): Result { val interim = repo1.save(datum) return repo2.destroy(someOp(interim)) } private fun someOp(input: String) = if (notLucky(input)) throw Exception("Sorry, bro") else input final by default
Всё final Прокси не создаются Конфигурации не работают Решения kotlin-allopen + kotlin-spring Код, который ты видишь не соответствует реальности ⇒ кодревью усложняется Конструкция хрупкая и иногда ломается Всюду явно писать open Опять бойлерплейт…
complex(datum: String): Result { val interim = repo1.save(datum) return repo2.destroy(someOp(interim)) } private fun someOp(input: String) = if (notLucky(input)) throw Exception("Sorry, bro") else input Spring + Kotlin. Part 2 @Transactional Exception
val username: String, private val pass: String ): UserDetails { override fun getUsername() = username override fun getPassword() = pass } Не только спринг
красивее чем в Java Алиасы в стандартном синтаксисе не работают Даже маппинг в data-классы Лямбды красивее Book b = BOOK.as("b") as — функция приведения в Kotlin val b = Book("b") Что нашли:
У меня нет опыта Проблема — no-arg constructor в data-классах Решение 1: не использовать data-классы Абыдно <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <configuration> <compilerPlugins><plugin>jpa</plugin></compilerPlugins> <jvmTarget>1.8</jvmTarget> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-noarg</artifactId> </dependency> </dependencies> Решение 2: плагины
есть автоматический вывод типов! class Controller { fun apiCall(arg: String) = run { val interim = myService.call(arg) postProcess(interim) } } Не делайте так!
2 Kotlin работает достаточно плохо Вообще, наверное, не используйте Котлин не умеет raw-types public class BrowserWebDriverContainer<SELF extends BrowserWebDriverContainer<SELF>> {...} BrowserWebDriverContainer<Nothing>() Не работают красивые билдеры class KBrowserWebDriverContainer() : BrowserWebDriverContainer<KBrowserWebDriverContainer>() Лапшекод и мусор
нужна библиотека kotlinx-support-jdk8 Работают даже лучше за счёт методов toList() и тд Стримы не нужны — есть asSequence() Который работает даже на массивах Больше функциональных методов Например, zip
name: String, @field:Min(18) val age: BigDecimal, @field:CustomAnno val parents: List<Person>? ) Сразу непонятно, но аннотации садятся на аргументы конструктора О которых hibernate- validator не знает Нас спасает ключевое слово field Иногда из-за логики сигнатура типа и аннотация конфликтуют
классы и плюшки — нужен jackson-module-kotlin Работает с конструктором! и с полями тоже Поддерживает Pair, Triple, Range import com.fasterxml.jackson.module.kotlin.* val mapper = jacksonObjectMapper()
одну: Either Удобно когда у тебя в JSON может быть один из двух объектов Нужно для того чтобы пробрасывать результат выполнения, когда часть кода написана в функциональном стиле Отлично подходит для Future
Например если функции лежат в Utils.kt – из джавы они будут выглядеть как UtilsKt.functionName() Иногда нам надо чтобы функция именовалась в джаве иначе @JvmName to the rescue!
проще Если весь код написан на Kotlin — то как правило можно не думать о null Множество библиотек с очень приятным синтаксисом делает код красивее Этого оказалось достаточно чтобы распространить практику Как мы раскатали практику на полкомпании