Что означает <ClassName>.() В Kotlin?
Не уверен, что это значит, но я столкнулся с этим синтаксисом в html кодовой базе kotlin. Что означает SCRIPT.()?
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.