这是哪个kotlin语言特性
Which kotlin language feature is this
我正在学习 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
class 是如何初始化的。它采用 CustomStep
的 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
}
谢谢
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
我正在学习 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
class 是如何初始化的。它采用 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
}
谢谢
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