четверг, 25 июля 2019 г.

Kotlin: Деструктуризация

Если вы Android разработчик, которые переходит с Java на Kotlin, одной из наиболее интересных функций, с которой придется столкнуться, является деструктуризация.

Деструктуризация позволяет разбить объект на несколько переменных. Например, у вас может быть класс Person, который состоит из имени и поля возраста:

data class Person (val name: String, val age: Int)

Деструктуризация экземпляров этого класса позволяет эффективно инициализировать переменные внутренними полями объекта Person, как показано ниже:

(1) val person = Person("Thomas", 40)(2) val (name, age) = person // деструктуризация(3) println("$name is $age years old")



>> Tomas is 40 years old


Деструктуризация здесь происходит во второй строке. За сценой происходит следующее:

val name = person.component1()
val age = person.component2()


Пример с Person это типичный пример, который вы можете найти в интернете. Выглядит красиво, но не совсем понятно как это можно использовать на практике.

Для ответа на этот вопрос посмотрим на функционал типичного приложения, допустим нам необходимо иметь дело с данными о местоположении.
Допустим, нам необходимо обрабатывать коллекцию истории объекта Location. Мы по возможности упростим пример, наш Project Manager просто попросил чтобы мы писали широту и долготу каждой позиции в лог.


Наш первый кусок кода может выглядеть примерно так:

fun processLocations(locations: List) {
    for (location in locations) {
        Log.d("TAG", "Lat: ${location.latitude}, Lon: ${location.longitude}")
    }
}


Ну или что-то вроде этого:
fun processLocations(locations: List) { 
    locations.forEach { 
        location -> Log.d("TAG", "Lat: ${location.latitude}, Lon: ${location.longitude}") 
    }
}

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

Сначала мы создадим методы расширения для существующего класса Android Location, чтобы мы могли использовать деструктуризацию:

operator fun Location.component1() = latitude
operator fun Location.component2() = longitude

Теперь, с этими доработками, мы можем изменить наш пример чтобы использовать деструктуризацию. Вот один из примеров:

fun processLocations(locations: List) {
    for ((lat, lon) in locations) {
        Log.d("TAG", "Lat: $lat, Lon: $lon")
    }
}

Или даже еще более краткий:

fun processLocations(locations: List) {
    locations.forEach { (lat, lon) -> println("Lat: $lat, Lon: $lon") }
}

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

















Комментариев нет: