我已经看过很多教程,但仍然没有确切地了解它是如何工作的。我理解其中的主要思想:一个用数据保存函数的函数,但看看正式文件,我不知道数据是如何存储的,数据存储在哪里,以及谁调用了负责其存储的函数。其他教程似乎只展示了一段代码片段,这对我没有多大帮助。你能给我一个简单完整的例子吗?你能给我一个简单的例子吗?
发布于 2018-01-16 17:02:45
我也对一些细节感兴趣。以下是我写的:
data class Person(
var name: String? = null,
var age: Int? = null,
val children: MutableList<Person> = ArrayList()
) {
fun child(init: Person.() -> Unit) = Person().also {
it.init()
children.add(it)
}
}
fun person(init: Person.() -> Unit) = Person().apply { init() }
fun main(args: Array<String>) {
val p = person {
name = "Mommy"
age = 33
child {
name = "Gugu"
age = 2
}
child {
name = "Gaga"
age = 3
}
}
println(p)
}它打印出(添加了一些格式):
Person(name=Mommy, age=33, children=[
Person(name=Gugu, age=2, children=[]),
Person(name=Gaga, age=3, children=[])
])发布于 2018-01-16 20:07:41
Kotlin DSL
Kotlin很适合编写您自己的域特定语言,也称为型安全建筑商。Anko就是使用这种DSL的例子之一。这里您需要理解的最重要的语言特性是“功能文字与接收者”,您已经使用了它:Test.() -> Unit
带接收基的函数字面值
Kotlin支持“带有接收者的函数文字”的概念。这使我们能够在其正文中调用函数文字的接收器上的方法,而不需要任何特定的限定符。这是非常类似于扩展函数的,在扩展函数中,也可以访问扩展内的接收方对象的成员。
一个简单的例子,也是Kotlin标准库中最大的函数之一,是apply。
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }正如您所看到的,这样一个带有接收方的函数文本被作为参数block在这里。简单地执行这个块,并返回接收器(它是T的一个实例)。在行动中,如下所示:
val foo: Bar = Bar().apply {
color = RED
text = "Foo"
}我们实例化Bar的一个对象并在其上调用apply。Bar的实例成为“接收者”。作为参数在block (lambda表达式)中传递的{}不需要使用附加限定符来访问和修改显示的可见属性color和text。
带有接收端DSL的函数文本
如果您从文档中看到这个示例,您将看到以下操作:
class HTML {
fun body() { ... }
}
fun html(init: HTML.() -> Unit): HTML {
val html = HTML() // create the receiver object
html.init() // pass the receiver object to the lambda
return html
}
html { // lambda with receiver begins here
body() // calling a method on the receiver object
}html()函数需要这样一个函数文字,接收机以HTML作为接收方。在函数体中,您可以看到它是如何使用的:创建了HTML的一个实例,并在其上调用了init。
优势
这样一个高阶函数的调用方期望一个带有接收方(如html())的函数文本,您可以使用任何可见的HTML函数和属性,而无需附加限定符(例如this ),正如您在调用中看到的那样:
html { // lambda with receiver begins here
body() // calling a method on the receiver object
}示例
我编写了一个示例DSL并在博客帖子中对其进行了描述。也许这也有帮助。
发布于 2022-07-25 07:03:12
只是为了添加其他语法
data class QCMBean(var qcmId : Int=-1, var question : String = "", var answers : ArrayList<AnswerBean> = ArrayList()) {
companion object {
fun qcm(init:QCMBean.()->Unit) = QCMBean().apply {
init()
}
}
fun answer(answer:String = "") = AnswerBean(answer).apply {
answers.add(this)
}
}
data class AnswerBean(var answer:String = "")
qcm {
qcmId = 1
question = "How many cat ?"
answer("1")
answer("2")
}https://stackoverflow.com/questions/48286031
复制相似问题