我一直在努力让 DSL 像这样工作。我想将 lambda 中的项目添加到人员内部的 mutableList 中。有人可以帮忙吗?
persons {
Person("name")
Person("name second")
}
执行 lambda 后的预期结果,所有这些项目将被放入 mutableList 中,如下所示:
mutableListOf(Person("name"), Person("name second"))
我一直在努力让 DSL 像这样工作。我想将 lambda 中的项目添加到人员内部的 mutableList 中。有人可以帮忙吗?
persons {
Person("name")
Person("name second")
}
执行 lambda 后的预期结果,所有这些项目将被放入 mutableList 中,如下所示:
mutableListOf(Person("name"), Person("name second"))
与您所拥有的不完全一样,但应该能够使用类似的东西
data class Person(var name: String? = null)
class Persons : ArrayList<Person>() {
fun person(block: Person.() -> Unit) {
val person = Person().apply(block)
add(person)
}
}
fun persons(block : Persons.() -> Unit): Persons = Persons().apply(block)
fun main() {
val personList = persons {
person {
name = "John"
}
person {
name = "Jane"
}
}
println(personList)
}
(这可以扩展为使用某种构建器模式以允许在数据类中使用不可变的 val)
假设这Person
是一个:
data class Person(val name: String)
然后该行Person("name")
什么都不做——它只是声明了一个未使用的实例。Person("name second")
做同样的事情(一般来说,因为它是 lambda 中的最后一行,所以它作为 lambda expsession 的结果隐式返回,理论上,它可以稍后处理;无论如何,该 DSL 语法在一般情况下不起作用)。
您不仅需要声明实例,还需要将它们添加到列表中。因此,您需要声明一些辅助函数(person
例如,接近所需的语法),它将在后台执行此操作:
class Persons {
val delegate: MutableList<Person> = mutableListOf()
fun person(name: String, block: Person.() -> Unit = {}) {
delegate.add(Person(name).also(block))
}
}
fun persons(block: Persons.() -> Unit) = Persons().also(block).delegate.toList() //mutation was needed only during construction, afterwards consider preserving immutability
用法:
val persons: List<Person> = persons {
person("name")
person("name second")
}