Публикация

Kotlin. Функция with()

Функция with чем-то похожа на шаблон билдер, но, конечно же, это очень грубое сравнение, о том, как на самом деле он работает и где применять пойдет речь в этой публикации.

Что такое Scope Function?

Scope Function - это не что иное, как функции, которые вызывается в области видимости нашего объекта.

Например, если вы работали с Extension Function, то scope функции по своей сути реализованы по такому же подходу и представлены как функции нашего объекта.

Как устроена функция with?

Прежде чем перейти к полному рассмотрению with на практике давайте заглянем под капот и посмотрим, как реализован with:

/**
 * Calls the specified function [block] with the given [receiver] 
 * as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

На первый взгляд мы можем видеть, что реализация очень похожа на let(), но тут есть два ключевых отличия:

  • Тип возвращаемого значения функции with это последнее выражение, которое мы вернули из переданного лямбда параметра;
  • В качестве первого параметра может быть передан любой объект.

Также, как и с let() используется contract {}, который вызовет наше лямбда выражение, передаваемое в качестве второго параметра.

Когда использовать?

Давайте представим тот же пример, когда у нас есть зарегистрированный пользователь без указанного email, который, к примеру, не обязательный при регистрации но пользователь может со временем его указать.

В нашем примере ниже приведет максимально простой код того, как пользователь решает указать свой email:

data class UserAccount(
    val firstName: String,
    var email: String? = null
)

fun main() {
    val user = UserAccount("Elon")

    val message = with(user) {
        email = "elon@domin.com"
        
        "Thank you, $firstName for sharing your email!"
    }
    
    println(message)
}

// >> Thank you, Elon for sharing your email!

Тут мы берем существующего пользователя и с помощью with добавляем email и формируем сообщение, которое отправим на эту же почту. Сообщение, последней строчкой лямбда выражения и будет возвращаемым значением.

Также, мы можем применять with, если нам нужно инициализировать множество полей объекта, при этом, не обращаясь к нему каждый раз через точку.

Если кроме инициализации полей мы ничего ниже не опишем, то возвращаемым типом with будет void.

Опубликовано: 15 июня 2021 г.Просмотров: 87

Комментарии

Мы не даем слово анониму 😶
Войдите, пожалуйста.

Еще никто не комментировал эту публикацию 🤔