Рубрики
Без рубрики

Берем Котлин на пробежку

Недавно моя жена купила Kindle Fire, и я подумал, что было бы забавно написать для него приложение. В f … С тегами java, kotlin, кодирование, мобильные устройства.

Недавно моя жена купила Kindle Fire, и я подумал, что было бы забавно написать для него приложение. На самом деле, вы можете вспомнить, что Я уже давно пытаюсь создать для нее библиотечное приложение . Что ж, что может быть лучше, чем дать ему еще один шанс, чем попробовать Kotlin.

Разработка мобильных приложений

Мои отношения с разработкой мобильных приложений были довольно краткими. На самом деле, мой единственный опыт работы с этим был моим последним семестром в старшей школе в 2016 году, когда Я создал приложение для Android для взаимодействия с интеллектуальным замком .

В то время я был знаком только с Java, C, Verilog и x86. Между прочим, это был ожидаемый репертуар для того, кто получил степень в области компьютерной инженерии. Несмотря на это, у меня не было большого опыта работы с чем-либо, кроме этих языков, поэтому я пошел по пути Android, чтобы использовать свой опыт Java.

Для тех, кому любопытно, мы использовали Arduino для управления электромагнитным замком. У Arduino было приложение Bluetooth, которое мы использовали для связи с замком через мобильное приложение для Android. Честно говоря, проект был довольно простым, но мне было очень весело разрабатывать что-то с нуля с многопрофильной командой.

Перенесемся на сегодняшний день, и вы обнаружите, что мало что изменилось — по крайней мере, до недавнего времени. Будучи полиглотом, я решил не только сделать еще один шаг в разработке мобильных приложений, но и попробовать свои силы в Kotlin.

Возвращение к Поп-библиотеке

Еще в начале 2016 года я решил создать библиотечное приложение Pop Library для моей тогдашней девушки Морган. Она хотела что-то, что она могла бы использовать для каталогизации своей коллекции книг, чтобы она могла одалживать их своим студентам, как в библиотеке.

Путь к провалу

Чтобы сделать вещи интересными, я решил расширить этот инструмент, чтобы потенциально заработать на нем немного денег. В частности, я хотел предоставить все те же функции, которые хотел Морган, с добавлением таких функций, как рекомендации по книгам. Затем эти рекомендации будут привязаны к моей учетной записи Amazon Associates, которая принесет мне большие деньги — или, по крайней мере, я так думал.

Оказывается, в течение двух лет я не мог воплотить это приложение в жизнь. Я думаю, у меня просто не было навыков, чтобы написать приложение с полным стеком, и эта реальность так и не наступила. В конце концов, я трижды пытался внедрить библиотеку Pop:

  • Приложение для Windows на C#
  • Приложение JavaFX
  • Веб-приложение Laravel

После трех попыток я сдался. Затем Морган купил Kindle Fire, и я снова пришел в восторг. По какой-то причине я чувствовал, что все может быть по-другому.

Меняющиеся требования

Потерпев три неудачи, на этот раз я решил, что сначала реализую всю функциональность, которую хочет Морган. Затем я попытаюсь посмотреть, смогу ли я заработать немного денег на стороне. С учетом сказанного библиотека Pop должна уметь выполнять следующие действия:

  • Отображение списка книг, которыми владеет пользователь
  • Разрешить пользователю добавлять и редактировать свои собственные книги (название, изображение и т.д.)
  • Сохранение данных книги локально (долгосрочная цель: облачное хранилище)
  • Предлагайте функции поиска и фильтрации для изменения в каких книгах отображаются
  • Разрешить пользователю одалживать книги другим пользователям
  • Используйте камеру для сканирования штрих-кодов

На данный момент у меня уже есть первые несколько реализованных функций, и я работаю над приложением всего около двух дней. За то, чтобы иметь опыт, платят!

Впечатления от Котлина

Все это говорит о том, что я уверен, что вы здесь не для того, чтобы узнать о моем проекте. Вы, вероятно, здесь по целому ряду причин, таких как:

  • Выяснение того, стоит ли проверять Kotlin или нет
  • Посмотреть, что новичок думает о языке
  • Разделяя некоторые из растущих болей

Какова бы ни была причина, вот мое мнение о Котлине на данный момент.

Спаси Себя от Нуля

Почти в каждом языке, с которым я имел удовольствие играть (C, C#, Java, Python, JavaScript, PHP и т. Д.), Было такое понятие null . Для меня null просто имело смысл. В конце концов, это идеальное значение для ссылочного типа, когда его значения не существует. Например, если вы предоставляете форму пользователю, и он решает не заполнять некоторые необязательные элементы, значения этих элементов под капотом должны быть нулевыми — не какое-то произвольное значение.

Ну, по крайней мере, таково было мое понимание null . Я не понимал, что это может быть такой проблемой. На самом деле, существует тонна литературы, касающейся null как одна из самых больших ошибок в информатике. Как ни странно, я не слышал об этой враждебности по отношению к нулю до тех пор, пока не написал свою статью Hello World в Swift в 2017 году.

Введение Обнуляемого

Из-за проблем, которые может вызвать null, многие современные языки пытались их устранить. По крайней мере, такие языки, как Kotlin и Swift, обернули null в объекты, что вводит некоторую проверку безопасности. Другими словами, больше никаких исключений NullPointerExceptions (NPEs), если вы их не просите.

В частности, в Kotlin вы можете установить для любой переменной значение nullable с помощью вопросительного знака:

var count: Int? = null

Здесь мы создали переменную с именем count типа Int? значение count может быть числом или нулем . При использовании count вы можете захотеть вызвать для него метод, подобный методу декремента:

count.dec()

В идеале этот метод уменьшал бы количество , но count на самом деле не является числом — это нуль . На большинстве языков мы получили бы NPE, но Kotlin фактически не сможет скомпилироваться. Чтобы приспособиться к этому, мы должны немного изменить синтаксис:

count?.dec()

Здесь мы выполнили безопасный вызов на считать . Если количество равно нулю , вся цепочка вернет null , но мы не получим NPE.

Обнуляемый на практике

Теперь это потрясающая функция для ненавистников null , но я обнаружил, что иногда она может усложнить жизнь. Например, я создал класс Book , который выглядит примерно так:

data class Book( 
  val isbn13: String? = null, 
  val title: String? = null, 
  val author: String? = null, 
  val editor: String? = null, 
  val language: String? = null, 
  val coverImageURL: String? = null, 
  val pageCount: Int? = null, 
  val dateOfPublication: Date? = null
) { }

Я установил для каждого поля значение nullable , потому что я не хочу заполнять эти поля произвольными данными. Другими словами, я не хочу настраивать строковые поля как пустые строки или какие-либо другие произвольные данные, потому что мне пришлось бы запоминать значение по умолчанию для проверки позже. Вместо этого я оставляю все незаполненные поля пустыми и решаю проблемы с нулем по мере их возникновения.

Тем не менее, я столкнулся с парой проблем. Например, если я хочу проверить, содержится ли строка в заголовке, я мог бы написать что-то вроде этого:

title?.contains("Gatsby", true)

Конечно, проблема здесь в том, что это выражение может возвращать значение true, false или null. На таком языке, как JavaScript, условия могли бы справиться с такой двусмысленностью, но не в Kotlin. В результате нам в основном приходится присваивать нулевому значению значение false с помощью оператора Элвис :

title?.contains("Gatsby", true) ?: false

Другими словами, если заголовок равен нулю затем выражение возвращает значение false.

Теперь представьте, что у вас есть какое-то условие, которое проверяет некоторые из этих условий. Очень быстро мы получаем беспорядочное выражение, которое требует, чтобы оператор Elvis обрабатывал любые нулевые возможности. В итоге я заключил приведенное выше выражение в функцию и объединил различные возможности вместе, используя оператор ИЛИ:

checkContains(title, str) 
  || checkContains(author, str) 
  || checkContains(editor, str) 
  || checkContains(language, str)

Очевидно, что это не идеально, но здесь нет NPE! Я полагаю, что у более опытных разработчиков Kotlin был бы лучший способ справиться с этой проблемой, но я просто пытаюсь запустить приложение.

Сравнение объектов с перегрузкой оператора

Хотя самой интересной особенностью Kotlin для меня является нулевая безопасность, я должен сказать, что перегрузка оператора занимает второе место. Обычно я был бы категорически против перегрузки операторов, поскольку это вносит ненужную сложность в язык, но я думаю, что Kotlin неплохо справляется с этой функцией.

К сожалению, для того, чтобы вы могли оценить эту функцию, вам нужно немного знать о том, как работает Java. В частности, вам необходимо быть знакомым с equals() методом объектов и compareTo() методом сопоставимого интерфейса.

Эквивалентность объектов

В Java все объекты имеют метод equals() , поэтому их можно проверить на равенство с другим объектом. Конечно, альтернативой equals() является оператор == , но он служит другой цели. Вместо проверки того, эквивалентны ли два объекта, оператор == проверяет, имеют ли два объекта одинаковую идентичность. Другими словами, если два объекта имеют одинаковую идентичность, то на самом деле они являются одним объектом с несколькими псевдонимами.

В Kotlin == используется повсеместно для равенства. Тем временем проверка личности выполняется с помощью оператора === . В результате == и равно( ) являются синонимами. Как только мы внедрим метод equals() , мы сможем использовать вместо него оператор == :

val x = Date(1000)
val y = Date(1000)
x.equals(y) // Evaluates equality based on equals() 
implementation x == y // Does the same exact thing

Как оказалось, IntelliJ на самом деле продвигает использование оператора вместо метода, и я его большой поклонник. Но подождите, все становится лучше!

Сравнение объектов

В Java, когда мы хотим сравнить два объекта — скажем, для целей сортировки, — мы обычно обязательно реализуем интерфейс Comparable . Как часть этого интерфейса, мы должны переопределить метод compareTo() , который принимает пару объектов и возвращает число, представляющее их взаимосвязь. Если два объекта эквивалентны, метод должен возвращать 0. Между тем, метод должен возвращать положительное число, если вызывающий объект является “большим” объектом, и отрицательное число в противном случае.

Определение того, какой объект “больше”, зависит от типа объекта, который мы используем. Например, строка “яблоко” меньше строки “морковь”, потому что алфавитный порядок диктует, что “яблоко” идет первым. Другими словами, compareTo должен вести себя следующим образом:

"apple".compareTo("carrot") // Returns some negative number
"carrot".compareTo("apple") // Returns some positive number

Во всяком случае, compareTo немного сбивает с толку, и Котлер отлично справляется с этой путаницей, вводя несколько операторов. Используя тот же пример, что и выше, мы можем сравнить “яблоко” и “морковь”, используя реляционные операторы:

"apple" > "carrot" // false
"apple" < "carrot" // true

Лично я использовал это для сортировки книг по уровню их лексики. В моем проекте, Lexile – это класс , который реализует Сопоставимый . Чтобы сравнить их, я использую их числовое значение:

override fun compareTo(other: Lexile): Int { 
  return this.toInteger() - other.toInteger()
}

Тогда я могу сравнить два Гибкие объекты следующим образом:

val lex1 = Lexile(270, Lexile.LexileType.NA)
val lex2 = Lexile(400, Lexile.LexileType.NA)
assertTrue(lex1 < lex2)

Так вот, я думаю, что это довольно круто.

Попрощайтесь с многословием

Одна из самых больших жалоб людей на Java – это многословие языка. В частности, определения переменных требуют огромного количества деталей:

ArrayList myList = new ArrayList()

Для того чтобы создать этот список, нам пришлось указать много информации:

  • Печатайте, дважды
  • Универсальный тип, дважды
  • Имя
  • Ключевое слово (новое)
  • Оператор (=)
  • Конструктор

Естественно, длина этой строки кода может увеличиваться в геометрической прогрессии в зависимости от таких факторов, как длина имени типа, количество вложенных универсальных типов и размер конструктора.

Чтобы справиться с этим, Kotlin вводит гораздо более краткий синтаксис:

val list = arrayListOf()

Очевидно, что здесь многое происходит, но важно принять к сведению отсутствие избыточной информации. Мы не указываем тип, но у нас есть возможность. Кроме того, заполнение ArrayList значительно проще:

val list = arrayListOf(5, 6, 8, -4)

Теперь, хотя уменьшенная детализация приятна, я также хотел бы отметить, что Kotlin также ввел два новых ключевых слова: val и различные . Мы используем val , когда хотим пометить переменную как неизменяемую или доступную только для чтения (подумайте final из Java) и var для обозначения переменной как изменяемой.

Овладение искусством управления потоком

Если я чему-то и научился, играя с языками программирования, так это множеству механизмов управления потоками. Например, есть операторы if и циклы только для начала. Кроме того, существуют забавные механизмы, такие как операторы goto и switch, которые предлагают еще больше возможностей для управления потоком.

Все это говорит о том, что Котлин представил мне еще один механизм управления потоком: когда . По сути, это оператор switch , но я нахожу синтаксис намного более чистым:

override fun toString(): String { 
  return when (this.type) { 
    LexileType.NA -> level.toString() + "L" 
    else -> type.name + level.toString() + "L" 
  }
}

В этом методе мы переопределили метод toString() для возврата строки при двух возможных условиях:

  • Тип – NA
  • Тип – это что-то другое

В частности, мы возвращаем результат оператора when , который принимает тип этого объекта (тот же Лексический класс из более раннего). Если тип NA, мы возвращаем некоторую строку. В противном случае мы вернем какую-нибудь другую строку.

На мой взгляд, оператор when является умным, потому что он удаляет много избыточного кода, который вы можете найти в операторе switch : break, return и т. Д. Естественно, я использую их довольно часто, потому что IntelliJ на самом деле предпочитает их цепочкам операторов if. Кроме того, я просто думаю, что они классные.

Вердикт

На данный момент мне очень нравится Котлин. Функцию нулевой безопасности было сложно обойти, но все остальное отлично. Kotlin – это все, что я люблю в Java, плюс все, что я люблю в языках более высокого уровня, таких как Python. Убрав большую часть шаблонов, я чувствую, что действительно могу быстро что-то создать, в то же время полагаясь на все удивительные утилиты статического анализа, которые входят в стандартную комплектацию скомпилированных языков.

Все это говорит о том, что скоро мы увидим, как я себя чувствую. Наверное, я просто нахожусь в фазе медового месяца, но мне действительно нравится этот язык. Это напоминает мне о том, что я чувствовал, когда впервые начал использовать C# — и то, и другое является большим улучшением по сравнению с Java.

Поскольку я впервые по-настоящему подробно изучаю язык, подобный этому, у меня действительно нет никаких статей, которые я мог бы порекомендовать. Как бы то ни было, вот пара статей, которые я хотел бы увидеть перед большим количеством глаз:

Камень Ножницы Бумага С Использованием Модульной Арифметики

Джереми Грифски ・ 18 ’19 марта ・ 11 мин читать

Размышляя о своем первом семестре преподавания

Джереми Грифски ・ 7 мая 19 ・ 17 минут читать

Кроме того, если вам понравилась эта статья, поделитесь ею! К тому времени, когда он будет опубликован, у меня, вероятно, будет совершенно другое мнение по этому вопросу, так что давайте тоже проведем диалог. Для тех из вас, кто хочет создать какое-то сообщество, перейдите на страницу участников и зарегистрируйтесь! Для менее преданных есть также информационный бюллетень . Как всегда, спасибо, что заглянули!

Сообщение Запуск Котлина появилось первым на Кодировщик-отступник .

Оригинал: “https://dev.to/renegadecoder94/taking-kotlin-for-a-spin-1322”