Я изучаю kotlin DSL, в частности Teamcity, и вижу шаблон инициализации, который я еще не совсем понимаю.
ссылка на игровую площадку Kotlin
Вот код
package org.arhan.kotlin
fun main() {
val project = project {
configuration {
step {
name = "step 1"
command = "hi"
}
customstep {
name = "flang"
anotherCommand = "derp"
command = "1111"
}
}
}
println(project.configurations[0].steps[1].command)
}
fun project(block: Project.() -> Unit): Project {
return Project().apply(block)
}
fun Project.configuration(block: Configuration.() -> Unit): Configuration {
val configuration = Configuration().apply(block)
configurations.add(configuration)
return configuration
}
fun Configuration.step(block: Step.() -> Unit): Step {
val step = Step().apply(block)
steps.add(step)
return step
}
class Project {
var configurations = mutableListOf<Configuration>()
fun build(block: Configuration.() -> Unit) = Configuration().apply(block)
}
class Configuration {
var steps = mutableListOf<Step>()
}
open class Step {
final lateinit var name: String
var command: String = ""
}
open class CustomStep(): Step(){
var anotherCommand: String = ""
constructor(init: CustomStep.() -> Unit): this(){
// what does this do?
init()
}
}
fun Configuration.customstep(block: CustomStep.() -> Unit): Step {
// how is this constructor initialized
val step = CustomStep(block)
steps.add(step)
return step
}
В частности, вопрос заключается в том, как инициализируется класс CustomStep
. Требуется лямбда с CustomStep
в качестве получателя (это правильная терминология?) .
Затем я вызываю init()
в конструкторе, который инициализирует только что созданный CustomStep
на основе переданного блока.
Я не уверен, как работает эта инициализация. Точнее, какая именно особенность языка Kotlin здесь используется.
И чем это отличается, если вместо этого я написал это следующим образом?
open class CustomStep(): Step(){
var anotherCommand: String = ""
// no constructor
}
fun Configuration.customstep(block: CustomStep.() -> Unit): Step {
// use apply vs. passing in the block
val step = CustomStep().apply(block)
steps.add(step)
return step
}
Спасибо