Todo kotlin что это
Если статья вам понравилась, то можете поддержать проект.
Коты забавные, поэтому ввели ключевое слово fun (есть спорное мнение, что на самом деле это сокращение от «function» для обозначения функций, которые являются аналогами методов в Java).
Объявление функции начинается с ключевого слова fun, затем идёт имя функции, в круглых скобках указываются параметры. Тип возвращаемого значения указывается после списка параметров и отделяется от него двоеточием. Функция всегда возвращает значение. Если вы сами не указали возвращаемое значение, то функция вернёт Unit, который схож с void, но является объектом.
Стандартный вывод «Hello Kitty» для Kotlin-программы (Desktop, не Android):
Данная функция ничего не возвращает. Напишем другую функцию, возвращающую результат.
Обратите внимание, что if является выражением в Kotlin, а не Java-оператором и соответствует тернарному оператору в Java:
Простую функцию, в которой блок состоит из одной строки кода, можно переписать в одну строчку.
Можно даже убрать возвращаемый тип. Гулять так гулять.
Такой способ подходит только для функций, в которых Kotlin способен самостоятельно разобраться, чего хотел разработчик, т.е. с телом-выражением в правой части. В правой части мы вычисляем какой-то результат, который обычно передавали в return. Теперь мы можем отказаться от return и фигурных скобок, и сразу присваивать результат функции.
В других случаях (тело-блок) вы обязаны указывать возвращаемый тип и использовать инструкцию return.
Функции верхнего уровня можно импортировать для сокращения кода.
Доступен вариант со звёздочкой.
Можно даже изменить имя и создать псевдоним при помощи ключевого слова as. Этот вариант может оказаться полезным, если имеются несколько одинаковых названий функций из разных пакетов и хочется избежать путаницы и конфликтов.
Именованные параметры
Мы привыкли, что при вызове метода следует соблюдать очерёдность параметров. С именованными параметрами такая необходимость отпала. Создадим новую функцию из двух параметров.
Вызывая функцию, мы можем не соблюдать порядок параметров, если явно будем прописывать имена параметров.
Несмотря на то, что мы поменяли местами параметры, итоговый результат всё равно будет работать правильно. Такой подход может пригодиться, когда вы не помните порядок и вам лень смотреть документацию.
Данный приём не сработает при работе с методами, написанными на Java. Поддержка именованных аргументов есть в Java 8, но Kotlin поддерживает совместимость с Java 6, поэтому приходится смириться. Возможно, в будущем, эта проблема решится автоматически, когда откажутся от поддержки старых версий.
Параметры по умолчанию
Добавим в класс активности новую функцию для вывода всплывающего сообщения (в примере используется функция-расширение).
Второй параметр использует значение по умолчанию и мы можем его не указывать при вызове. Вызываем функцию.
С параметрами по умолчанию нужно быть внимательными, возможна ситуация, когда Kotlin не поймёт, что вы от него хотите. Создадим функцию из трёх параметров, один из них будет иметь значение по умолчанию.
Вызываем функцию с двумя параметрами, надеясь, что третий подставится самостоятельно. Но Kotlin не может решить, какой параметр пропущен.
В этом случае на помощь приходят именованные параметры.
Третий параметр теперь нам известен, опущенный параметр относится ко второму, оставшийся относится к первому.
У класса Thread имеется восемь конструкторов! Вы можете создавать гораздо удобные решения с параметрами по умолчанию.
Unit. Если функция ничего не возвращает
Стоит немного рассказать о функциях, которые не возвращают никаких значений. В Java мы используем ключевое слово void для подобных случаев. В Kotlin был придуман новый тип Unit для подобных ситуаций. Получается, что функция всегда что-то возвращает, в нашем случае Unit, который мы никак не используем.
Но Kotlin достаточно умен и понимает, что мы не хотим ничего возвращать. Поэтому мы можем сократить код.
Можно сократить код, убрав фигурные скобки, так как у функции только одно выражение.
Вызываем функцию с любым количеством аргументов.
Если функция имеет и другие параметры, то они должны быть раньше vararg. Можно обойти это правило, если использовать именованные параметры, но лучше избегать таких ситуаций.
По сути vararg работает с массивом, но простое добавление массива Kotlin не пропустит. Следует использовать специальный оператор *.
Вложенные (локальные) функции
Внутри одной функции можно создать ещё одну локальную функцию.
Вложенная функция имеет доступ к переменным своей родительской функции.
Функции верхнего уровня
Функцию можно объявить в начале файла, не обязательно размещать его в теле класса. Это удобно, когда вам нужны методы, которые не относятся к конкретному классу или вы не хотите перезагружать имеющийся класс лишним кодом. Часто для этих целей программисты создавали отдельные классы со словом Util.
Размещая код метода за пределами класса, вы избегаете лишней вложенности. Они по-прежнему являются членами пакета, прописанного в файле и могут импортироваться при использовании в других пакетах.
Таким образом можно создать новый файл без всяких классов, указав только пакет.
Kotlin незаметно для вас создаст класс CatsKt по имени файла и все функции скомпилирует в статические методы. Если будете вызывать функцию в Java-коде, то это будет выглядеть следующим образом.
Если имя класса вас не устраивает, то добавьте аннотацию @JvmName перед именем пакета.
Тогда вызов в Java-коде будет другим.
Функция TODO()
В стандартную библиотеку Kotlin входит функция TODO() (надо сделать). Её описание выглядит следующим образом.
Функция TODO() возбуждает исключение, т.е. вызов функции гарантированно завершится ошибкой — она возвращает тип Nothing. Считайте функцию временной заглушкой. Разработчик знает, что некоторая функция должна вернуть строку или другой объект, но пока отсутствуют другие функции, необходимые для ее реализации. Создадим для примера две функции.
Обратите внимание, что возвращаемое значение для shouldReturnAString() — это String, но на самом деле функция ничего не возвращает. Аналогично у shouldReturnACat().
Возвращаемый тип Nothing у TODO() показывает компилятору, что функция гарантированно вызовет ошибку, поэтому проверять возвращаемое значение после TODO() не имеет смысла, так как shouldReturnAString() и shouldReturnACat() ничего не вернут. Компилятор не будет ругаться, а разработчик может продолжать разработку, отложив на потом реализацию функции-заглушки.
Функцию можно вызвать без аргументов. Код, который будет следовать за функцией, будет недостижим.
Имена функций в обратных кавычках
Можно объявить или вызвать функцию с именем, содержащим нестандартные символы. Для этого достаточно заключить имя в обратные кавычки `. Например, объявим функцию:
Данная возможность нужна, чтобы поддерживать совместимость с Java в тех моментах, когда встречаются зарезервированные ключевые слова. Использование обратных кавычек позволяют избежать несовместимости в случаях, если это необходимо. На практике такое почти не встречается.
На данный момент под Android такой способ не работает, студия будет ругаться.
Функции
Объявление функций
В Kotlin функции объявляются с помощью ключевого слова fun
Применение функций
При вызове функции используется традиционный подход
Для вызова вложенной функции используется знак точки
Инфиксная запись
Функции так же могут быть вызваны при помощи инфиксной записи, при условии, что:
Параметры
Параметры функции записываются аналогично системе обозначений в языке Pascal, имя:тип. Параметры разделены запятыми. Каждый параметр должен быть явно указан.
Аргументы по умолчанию
Параметры функции могут иметь значения по умолчанию, которые используются в случае, если аргумент функции не указан при её вызове. Это позволяет снизить уровень перегруженности кода по сравнению с другими языками.
Значения по умолчанию указываются после типа знаком =.
Переопределённые методы всегда используют те же самые значения по умолчанию, что и их базовые методы. При переопределении методов со значениями по умолчанию эти параметры должны быть опущены:
Если параметр по умолчанию предшествует параметру без значения по умолчанию, значение по умолчанию можно использовать только при вызове функции с именованными аргументами:
Но если последний аргумент lambda передается в вызов функции вне скобок, передача значений параметров по умолчанию не допускается:
Именованные аргументы
Имена параметров могут быть явно указаны при вызове функций. Это очень удобно, когда у функции большой список параметров, в том числе со значениями по умолчанию.
Рассмотрим следующую функцию:
мы можем вызвать её, используя аргументы по умолчанию
Однако, при вызове этой функции без аргументов по умолчанию, получится что-то вроде
С помощью именованных аргументов мы можем сделать код более читабельным:
Или, если нам не нужны все эти аргументы
Переменное число аргументов (vararg) можно передать в именованной форме с помощью оператора spread:
Обратите внимание, что синтаксис именованных аргументов не может быть использован при вызове Java функций, потому как байт-код Java не всегда сохраняет имена параметров функции.
Функции с возвращаемым типом Unit
Указание типа Unit в качестве возвращаемого значения тоже не является обязательным. Код, написанный выше, совершенно идентичен с
Функции с одним выражением
Когда функция возвращает одно-единственное выражение, фигурные скобки < >могут быть опущены, и тело функции может быть описано после знака =
Компилятор способен сам определить типа возвращаемого значения.
Явные типы возвращаемых значений
Функции, в которых есть тело, всегда должны указывать возвращаемый ими тип данных (если в этом качестве не указан тип Unit ). Kotlin не вычисляет самостоятельно тип возвращаемого значения для функций с заключённым в них блоком кода потому, что подобные функции могут иметь сложную структуру и возвращаемый тип неочевиден для читающего этот код человека (иногда даже для компилятора).
Нефиксированное число аргументов (Varargs)
Параметр функции (обычно для этого используется последний) может быть помечен модификатором vararg :
это позволит указать множество значений в качестве аргументов функции:
Область действия функций
В Kotlin функции могут быть объявлены в самом начале файла. Подразумевается, что вам не обязательно создавать объект какого-либо класса, чтобы воспользоваться его функцией (как в Java, C# или Scala). В дополнение к этому, функции в языке Kotlin могут быть объявлены локально, как функции-члены (ориг. «member functions») и функции-расширения («extension functions»).
Локальные функции
Kotlin поддерживает локальные функции. Например, функции, вложенные в другие функции
Такие локальные функции могут иметь доступ к локальным переменным внешних по отношению к ним функций (типа closure). Таким образом, в примере, приведённом выше, visited может быть локальной переменной.
Функции-элементы
Функции-элементы вызываются с использованием точки
Для более подробной информации о классах и их элементах см. Классы
Функции-обобщения (Generic Functions)
Функции могут иметь обобщённые параметры, которые задаются треугольными скобками и помещаются перед именем функции
Для более подробной информации об обобщениях см. Обобщения
Встроенные функции (Inline Functions)
О встроенных функциях рассказано здесь
Функции-расширения (Extension Functions)
О расширениях подробно написано в отдельной статье
Высокоуровневые функции и лямбды
О лямбдах и высокоуровневых функциях см. раздел Лямбды
Функции с хвостовой рекурсией
Kotlin поддерживает такой стиль функционального программирования, более известный как «хвостовая рекурсия». Это позволяет использовать циклические алгоритмы вместо рекурсивных функции, но без риска переполнения стэка. Когда функция помечена модификатором tailrec и её форма отвечает требованиям компилятора, он оптимизирует рекурсию, оставляя вместо неё быстрое и эффективное решение этой задачи, основанное на циклах.
Этот код высчитывает fixpoint косинуса, который является математической константой. Он просто напросто постоянно вызывает Math.cos, начиная с 1.0 до тех пор, пока результат не изменится, приняв значение 0.7390851332151607. Получившийся код эквивалентен вот этому более традиционному стилю:
Функции в Kotlin для начинающих
Функции являются основой многих языков программирования. Проще говоря, функция позволяет определить блок кода, который выполняет определенную задачу. Затем, если приложению требуется выполнить данную задачу, можно вызвать функцию вместо того, чтобы копировать и вставлять везде одинаковый код.
Содержание статьи
В этом уроке вы узнаете, как создавать собственные функции, и увидите, как Kotlin упрощает их использование.
Создание новой функции в Kotlin
Представьте, что у вас есть приложение, которому часто требуется выводить ваше имя. Для этого можно создать функцию:
Приведенный выше код известен как объявление функции.
Подробнее о необходимости этих скобок обсудим ниже.
После круглых скобок следует открывающая фигурная скобка, за которой идет код, который нужно запустить в функции, а затем закрывающая скобка. После определения функции ее можно вызвать следующим образом в главной функции main() :
Вывод будет следующим:
В прошлых уроках мы уже использовали функции. Функция println выводит результат на консоль. Ниже вы узнаете, как передавать данные в функцию и получать данные взамен.
Параметры функции в Kotlin
В предыдущем примере, функция просто выводит на экран сообщение. Это здорово, но зачастую для функции требуется настроить параметры, с помощью которых она будет работать по-разному в зависимости от данных, которые в нее передаются.
В качестве примера рассмотрим следующую функцию:
Здесь дается определение одного параметра value типа Int в круглых скобках после названия функции. В любой функции круглые скобки содержат так называемый список параметров. Эти круглые скобки необходимы как при объявлении, так и при вызове функции, даже если список параметров пуст.
Данная функция выведет любое заданное число умноженное на пять. В этом примере вызывается функция с аргументом 10, поэтому вывод будет следующим:
На заметку: Не путайте термины «параметр» и «аргумент». Функция объявляет свои параметры в списке параметров. При вызове функции вы предоставляете значения в качестве аргументов для параметров функции.
Можно написать функцию более обобщенной. С двумя параметрами, функция выведет результат умножение любых двух значений.
Иногда при вызове функции будет правильнее использовать именованные аргументы, это упрощает понимание назначения каждого аргумента.
Теперь при вызове функции очевидно, для чего нужны аргументы. Это особенно полезно, когда у функции несколько параметров.
Вы также можете назначить параметрам значения по умолчанию:
Мы добавили = 1 после второго параметра. Это значит, что при отсутствии значения для второго параметра значение по умолчанию будет равно 1.
Таким образом, вывод кода будет следующим:
Иметь значение по умолчанию может быть полезно, когда вы ожидаете, что у параметра будет одно конкретное значение большую часть времени, и это упростит код при вызове функции.
Функции и оператор возврата return в Kotlin
Все рассматриваемые до сих пор функции выполняли простую задачу — они что-то выводили в консоль. Функции также могут возвращать значение. При вызове функции можно присвоить возвращаемое значение переменной или константе или использовать его непосредственно в if или when выражениях в качестве значения для проверки.
Это означает, что функцию можно использовать для управления данными. Данные просто принимаются через параметры, они изменяются внутри функции, а затем возвращаются.
Определить функцию, возвращающую значение, можно следующим образом:
Внутри функции используется оператор return для возврата значения. В этом примере возвращается результат от умножения двух параметров.
Также можно вернуть несколько значений с помощью Pair:
Параметры в качестве значений в Kotlin
Рассмотрим следующим пример кода:
Результатом выполнения данного кода будет ошибка:
Обычно такое поведение ожидаемо. В идеале функция не меняет свои параметры. Если это так, то вы не можете быть уверены в значениях параметров и можете сделать неверные предположения касательно кода, что приведет к ошибочным данным при их использовании.
Если нужно, чтобы функция изменила параметр и вернула его, вы должны сделать это косвенно, объявив новую переменную следующим образом:
На заметку: Как вы увидите в будущем, при добавлении параметров к основному конструктору при определении класса вы действительно добавляете var или val к параметрам. Это делается для указания, что параметры являются свойствами класса и что их значение может или не может быть изменена.
Перегрузка функций в Kotlin
Что делать, если вам нужно использовать несколько функций с одним и тем же названием?
Это перегрузка, которая дает возможность определить похожие функции, используя одинаковое название для них, НО с разными типами параметров.
Однако, компилятор по-прежнему должен видеть разницу между данными функциями внутри текущей области видимости. Каждый раз при вызове функции должно быть понятно, какая функция будет выполняться.
Обычно это достигается через разницу в списке параметров:
На заметку: Одного возвращаемого типа недостаточно для различия двух функций. Т.е. если одна функция возвращает Int а другая возвращает строку — этого будет недостаточно, чтобы компилятор понял какую из них вызвать ведь тип у параметров один и тот же.
К примеру, такое определение двух методов приведет к ошибке:
У методов выше одинаковые названия, типы параметров и количество параметров. Kotlin не может различить их!
Стоит отметить, что перегрузку нужно использовать осторожно. Используйте перегрузку только для тех функций, поведение которых похоже но из за разных типов у параметров у них будет разная обработка данных внутри функции.
Задания для проверки
Функции как переменные в Kotlin
Функции в Kotlin являются просто еще одним типом данных. Их можно присваивать переменным и константам как и значения любого другого типа вроде Int или String.
Рассмотрим следующую функцию:
Данная функция принимает два параметра и возвращает сумму их значений.
Вы можете присвоить данную функцию переменной через использование метода создания ссылки :: следующим образом:
Теперь можно использовать переменную function так же, как использовалась бы функция add :
Данный код выведет на экран: 6
Теперь рассмотрим следующий код:
Назначение функций переменным может быть очень удобным, потому что таким образом вы можете передавать функции другим функциям. Далее дан показательный этому пример:
Функция printResult принимает три параметра:
Возможность передавать функции другим функциям очень полезна. Вы можете не только передавать данные для различных манипуляций с ними, но и функции в качестве параметров. Это также означает, что вы можете гибко выбирать какой именно код будет выполняться.
Присваивание функций переменным и передача функций в качестве аргументов — это один из аспектов функционального программирования, о котором вы подробнее узнаете в будущих уроках.
Невозвращаемые функции в Kotlin
Это может показаться запутанным, но мы все-таки рассмотрим пример функции, которая предназначена для сбоя работы приложения. Если приложение собирается работать с поврежденными данными, зачастую лучше завершить работу вместо продолжения работы в неизвестном и потенциально опасном состоянии.
Другим примером невозвращаемой функции является функция, которая обрабатывает цикл событий. Цикл событий лежит в основе каждого современного приложения, которое принимает данные от пользователя и отображает их на экране. Цикл событий обслуживает запросы, поступающие от пользователя, а затем передает эти события в код приложения, который вызывает отображение информации на экране. Затем цикл возвращается назад и обслуживает следующее запросы.
Эти циклы событий часто запускаются в приложении путем вызова функции, которая никогда не возвращается. Если вы начинаете разрабатывать приложения для Android, помните об этом, когда столкнетесь с основным потоком, также известным как поток UI, или поток пользовательского интерфейса.
У Kotlin есть способ сообщить компилятору, что функция никогда не вернет значение. Вы устанавливаете тип возвращаемого значения функции на тип Nothing, указывая на то, что функция никогда ничего не возвращает.
Грубая, но честная реализация невозвращаемой функции будет выглядеть следующим образом:
ToDo List App with Kotlin and Firebase
Firebase is a real-time database which provides immense features to manage a mobile app. Actually, not even a mobile app, complex web apps and enterprise applications can make use of Firebase with virtually unlimited performance.
In this lesson we will cover many of Firebase features and its usage, using a simple ToDo app build with Kotlin and powered by Firebase Database API. Let’s get started.
Firebase
Firebase offers many features with its strong API and unlimited performance. We will mention some of these here:
New Project in Android
We will be creating a new project in Android to demonstrate a simple app as a ToDo List app build with Kotlin and using Firebase Database with a complete set of CRUD(Create, Read, Update Delete) operations.
Adding Firebase support
Next, we add Firebase support in our application. This can be done easily from inside the Android Studio itself. Click Tools > Firebase to open the Assistant window.
Once that is done, the Firebase assistant will appear presenting many Firebase services, we need to select the `Realtime Database` feature:
Once you click ‘Setup Firebase Realtime Database’, following dialog will appear to confirm setting up the project:
Next, Android Studio will offer to add relevant code snippets to our app like Gradle dependency:
With other changes, it is clearly shown in the dialog Android Studio presented us:

Setting Firebase project access rules
This lessons is not meant for authentication purposes. So, the ToDo items we add in our app will be accessible to all the users using the same app as we’re accessing the same database irrespective of the user identity. So, to make our database public, we will add the following script in our Firebase project access rules:

In the Data tab above, you will find a URL like:
Though this URL is not important as our app will access the Firebase over the network and Firebase will identify which database to access via the app’s package name itself and the google-services.json file added automatically by Firebase during its setup.
Add Database collection name
We will add our Database collection name in a new File in Kotlin whose content will be as follows:
Our collection name will be todo_item. We will see where will this appear as soon as we save first item in Firebase.
As of now, our Database on Firebase looks like:
Adding a To Do Item model
Here, we will design a model object which will be used to hold data for our ToDo list item data. We will intentionally keep this very simple for demonstration purposes.
Let us understand what we’ve done in this simple model:
Designing the app
Now that the complete configuration is done and we’ve finalised the data model, we can start working on the simple but intuitive design.
We need following functionalities in our app:
To start, we need following elements:
Our initial UI will look like this:
To make this simple UI, we kept these properties in XML in res > layout > activity_main.xml file as:
When this FloatingActionButton is clicked, we need to show a dialog with an EditText where user can enter new item and save it with Database.
Showing a Dialog on FloatingActionButton click
To do this, we must do following steps:
Let’s make changes to our Activity now. We first define a FloatingActionButton in onCreate(…) method which points to the FloatingActionButton in our XML above.
Then we set a click listener on it.
In addNewItemDialog function, we will show a dialog. As of now, our complete onCreate(…) method looks like:
Let’s add the method to show the dialog next:
Once we add the above code, alert dialog will appear once we hit the FloatingActionButton:
Creating entry in Firebase
This is where our real journey starts. In this section, we will start inserting data into the Firebase. We have already shown the current state of the database. Now, let’s modify the code of positive button listener of the dialog as:
Let us see what we did above:
We’ve used mDatabase in above code. What is it?
mDatabase is the Firebase database reference. Let’s create it as a Global variable in our Activity.
And initialise it in our onCreate(…) method:
As simple as that. Now, run the app once again, enter some value and hit ‘Submit’. The item will appear in the Firebase Database as:
Reading Firebase data in a List
What is the use of the data until and unless we’re able to read the data. In the previous section, we designed a simple UI with a ListView. Now, we will enhance it with custom UI for its row.
This is a simple UI which will create following row design:
Clearly, this row is enough to update item state as done using the CheckBox and to delete the row via the ImageButton.
To populate the ListView, we must create a new Adapter which will complete this responsibility.
In above adapter, we:
Now, we must use this Adapter in our Activity. Also, we also have to fetch data from Firebase.
Fetching data from Firebase
Getting data from Firebase is actually easy. Just do this in onCreate(…) method:
We will add item listener next. We just add a listener for current database which will fetch and alert the function when the data has been fetched.
We first define some global variables, as:
We will initialise each of them in our onCreate(…) method. Once all this is done, our method will look like:
Finally, our listener looks like:
What each line does is explained in above code itself. Now, we’re ready to show the data in our ListView. Once we run our app now, we can see the data as:
We are left with two operations. Updating the item as done or undone by checking that CheckBox. Second by clicking on that cross image to delete this data.
Update and Delete ToDo items
Now, to perform these operations. We must know when each of our row is clicked. Also, we need to get the ObjectID of the row that was clicked. This can be obtained from the Adapter.
Let’s start by creating an Kotlin Interface file as:
Clearly, we want to provide two operations.
Next, we will make our activity implement this interface by doing:
As we’ve implemented an interface, we must implement its methods as well:
We need to call these methods via our adapter. In our getView(…) method, we can do as:
This can only be done if we define rowListener in our Adapter class:
Now, once we click on checkbox as done, our database will change as:
Value has been changed.
Persisting Firebase data offline
Firebase is excellent in caching data. Once you run the app and get your data, Firebase will cache to so that it can be used offline as well. Once your app is back online, it will update the data.
The caching behaviour is off by default. Let’s modify this behavior.
We will create an Application class now:
That’s it! Just a single line of code and caching is enabled. Of course, you need to add this Application class in your Manifest file:
Our full fledged To Do Item application is ready.
Conclusion
In this lesson, we looked at CRUD(Create, Read, Update, Delete) operations of Firebase and how fast it is to sync with web server. We completed CRUD operations in our elegant app and enjoyed it as well.
Firebase also has strong caching techniques through which it promises strong user experience by presenting them data even when there is no network. We can do a lot more with Firebase like saving images etc. Let’s save it for another time.
To learn more about Mobile Apps Development with Kotlin check out the below books and video courses, they will certainly help you speed up your learning progress.









