путаница с пониманием лямбды и приемников - PullRequest
0 голосов
/ 07 октября 2018

kotlin 1.2.50

Я следил за некоторыми примерами из этого урока на youtube https://www.youtube.com/watch?v=gPH9XnvpoXE. И есть несколько вещей, которые я понял, но есть некоторая путаница.Я оставил комментарии в коде ниже, где я не уверен, что происходит.

fun main(args: Array<String>) {

    val javaClient = createClient {
        firstName = "joe"
        lastName = "bloggs"

        twitter {
            handle = "@joebloggs"
        }
    }

    println(javaClient.toConsole)
}

/* Are we passing in a lambda and receiver. What will the receiver be */
private fun JavaClientBuilder.twitter(suppler: JavaTwitterBuilder.() -> Unit) {
    /* We call JavaTwitterBuilder().apply(..) Will apply return the newly created object? Not sure why we have to pass the suppler in the apply */
    twitter = JavaTwitterBuilder().apply(suppler).build()
}

/* Are we passing in a lambda and receiver that return nothing */
private fun createClient(suppler: JavaClientBuilder.() -> Unit): JavaClient {
    val javaClientBuilder = JavaClientBuilder()

    /* confusion: Not sure about this, as we are calling suppler. Just wondering is the suppler the the JavaClientBuilder that was called in the above javaClient {} lambda */
    javaClientBuilder.suppler()

    return javaClientBuilder.build()
}

/* I understand this, an extension function that formats and returns the string from the JavaClient object it was called on */
private val JavaClient.toConsole: String
    get() =
        "Created client is: ${twitter.handle} ${company.name}"

Большое спасибо заранее,

1 Ответ

0 голосов
/ 07 октября 2018

/ * Проходим ли мы в лямбду и ресивер.Каким будет получатель * /

частного удовольствия JavaClientBuilder.twitter (suppler: JavaTwitterBuilder. () -> Unit)

У нас действительно есть получатель в этой функции, иэто экземпляр JavaClientBuilder, на который будет вызвана эта функция.

/ * Мы вызываем JavaTwitterBuilder (). Apply (..) Будет ли применять возврат вновь созданного объекта?Не уверен, почему мы должны передать сторонник в apply * /

twitter = JavaTwitterBuilder (). Apply (suppler) .build ()

Чтобы понять, как работает apply()взгляните на его исходный код (упрощенная версия):

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

Это функция расширения, объявленная для получателя типа T и возвращающая экземпляр T, который принимает блок -другая функция расширения с приемником типа T, возвращающая Unit.Обычно он используется для замены шаблона Builder - примените пользовательскую логику инициализации к объекту.В вашем случае suppler - это блок, который содержит логику инициализации для экземпляра JavaTwitterBuilder.Код функции создает экземпляр и использует apply() с логикой в ​​suppler для инициализации этого экземпляра.

/ * Мы передаем лямбду и получатель, которые ничего не возвращают * /

private fun createClient (suppler: JavaClientBuilder. () -> Unit): JavaClient

В этом случае createClient() не имеет приемника, это функция верхнего уровня.

/ * путаница: Не уверен насчет этого, так как мы называем Suppler.Просто интересно, является ли сторонник JavaClientBuilder, который был вызван в вышеупомянутом javaClient {} lambda * /

javaClientBuilder.suppler ()

suppler - это лямбда с JavaClientBuilderбудучи типом получателя, который позволяет нам вызывать его для только что созданного экземпляра JavaClientBuilder.

/ * Я так понимаю, это функция расширения, которая форматирует и возвращает строку из объекта JavaClientон был вызван * /

private val JavaClient.toConsole: String get () = "Создан клиент: $ {twitter.handle} $ {company.name}"

Правильно!Просто небольшая поправка, это расширение .Свойства могут иметь собственные методы получения и установки.Это свойство определяет пользовательский метод получения, поэтому при каждом обращении к этому свойству оно создает строку с форматом, описанным кодом получения.

...