Что означает <ClassName>.() В Kotlin?

Не уверен, что это значит, но я столкнулся с этим синтаксисом в html кодовой базе kotlin. Что означает SCRIPT.()?

https://github.com/Kotlin/kotlinx.html/blob/master/shared/src/main/kotlin/generated/gen-tag-unions.kt#L143

fun FlowOrPhrasingOrMetaDataContent.script(type : String? = null, src : String? = null, block : SCRIPT.() -> Unit = {}) : Unit = SCRIPT(attributesMapOf("type", type,"src", src), consumer).visit(block)

SCRIPT - это класс - https://github.com/Kotlin/kotlinx.html/blob/master/shared/src/main/kotlin/generated/gen-tags-s.kt.

Или, в целом, что делает <ClassName>.() значит в котлине?

2 ответа

Решение

Быстрый ответ

block: SCRIPT.() -> Unit = {}

Это представляет "литерал функции с получателем". Это параметр функции с типом функции () -> Unit а также SCRIPT как это получатель.

Функциональные литералы / лямбда с приемником

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

Простой пример, также одна из величайших функций в стандартной библиотеке Kotlin, этоapply:

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

Как видите, в качестве аргумента принимается такой литерал функции с получателем block Вот. Этот блок просто исполняется и получателем (который является экземпляром T) возвращается. В действии это выглядит следующим образом:

val foo: Bar = Bar().apply {
    color = RED
    text = "Foo"
}

Мы создаем объект Bar и позвонить apply в теме. Пример Bar становится "получателем". blockпереданный в качестве аргумента в {}(лямбда-выражение) не нужно использовать дополнительные квалификаторы для доступа и изменения отображаемых видимых свойств color а также text,

Концепция лямбды с приемником также является наиболее важной особенностью для написания DSL с Kotlin.

Что означает.() В Котлине?

Он называется функциональным литералом (или лямбда) с получателем.

Пример, чтобы попытаться объяснить то же самое:

      data class Person(val name: String)

fun getPrefixSafely(
    prefixLength: Int,
    person: Person?,
    getPrefix: Person.(Int) -> String): String
{
    if (person?.name?.length ?: 0 < prefixLength) return ""
    return person?.getPrefix(prefixLength).orEmpty()
}

// Here is how getPrefixSafely can be called
getPrefixSafely(
    prefixLength = 2,
    person = Person("name"),
    getPrefix = { x -> this.name.take(x) }
)

PS: Эти функциональные литералы с типами приемников аналогичны функциям расширения IMO.

Другие вопросы по тегам