我正在学习kotlin DSL,特别是Teamcity,我看到了一个我还不太理解的初始化模式
以下是代码
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 as the reciever的lambda中(这是正确的术语吗?)
然后我在构造函数中调用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
}谢谢
发布于 2021-07-22 20:34:46
init()正在引用参数init: CustomStep.() -> Unit
constructor(init: CustomStep.() -> Unit): this(){
// vvvv ^^^^
init()
}您只是在this上调用您传入的内容。毕竟,init需要一个CustomStep作为接收器。与在this上调用某些东西时的大多数情况一样,可以省略this,这就是这里发生的情况。对于customStep,您传入了block。
val step = CustomStep(block)block是来自main的这个位
{
name = "flang"
anotherCommand = "derp"
command = "1111"
}您的CustomStep().apply(block)替代方案也是一样的。调用您声明的辅助构造函数将首先调用无参数的主构造函数,因为您已声明为: this(),and is required。这与CustomStep()相同。然后两个版本都会在this上调用block。
https://stackoverflow.com/questions/68484618
复制相似问题