В kotlin лямбде, как строка принимает лямбда?
В gradle-kotlin-dsl... это действительный код
tasks {
"build" {
// inner lambda code here
Как это может работать, что строка может принимать лямбда-параметр, или как работает этот синтаксис? Строка "build" кажется одной из списка строк, которые заменяют вызовы функций? Что-то в применимом определении класса должно настроить это поведение, но я не могу думать, как это сделать.
То, как это работает, может быть техникой, которая имеет другое применение, но чтобы оценить это, необходимо знать, как это работает!
1 ответ
Это сочетание пары возможностей языка Kotlin, которые часто используются для создания DSL, а именно:
- оператор вызова, который позволяет вам определить
()
оператор вызова функции для типа с произвольным списком параметров ( docs) - возможность передать последний параметр лямбда-функции в функцию вне паратезов, которые обычно необходимы для списка параметров ( документы)
- расширения, позволяющие добавлять новые методы к существующим типам, даже если вы не являетесь их владельцем ( документы)
Чтобы получить синтаксис, о котором вы спрашивали конкретно, вы можете написать такой метод:
operator fun String.invoke(block: () -> Unit) {
// Do whatever you'd like with the String and the lambda
// you received as a parameter
}
Лямбда, которую вы берете в качестве параметра, также может быть расширением для любого типа, который вам нужен (возможно, String
само по себе, но зависит от вашего варианта использования), может принимать параметры, или ожидается, что будет возвращать значение, а не просто Unit
,
Дело в том, что внутри этого расширения вы будете иметь доступ к String
это называлось как this
и у вас будет лямбда, которая была передана ему.
Для дальнейшего ознакомления, вот статья из нескольких частей, которая демонстрирует некоторые методы построения DSL.