问题
我正在尝试理解以下代码
- 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.init() // 将接收者对象传递给 lambda
这里发生了什么?
有人可以简要解释一下这里发生了什么吗?
回答
首先,让这个例子保持简单,看看问题出在哪里。
我们可以像这样构建 html 函数:
- fun html(init: (HTML) -> Unit): HTML {
- val html = HTML()
- init(html)
- return html
- }
复制代码
这将更容易理解(起初),因为我们只是将通常的单参数 lambda 传递给 html 函数。
但是现在调用站点不像构建器:
- html { it: HTML -> // just for clarity
- it.body() // not very nice
- }
复制代码
如果我们可以在没有 body() 的情况下在 html 中调用它,那不是很好吗?这是可能的!我们只需要一个带有接收器的 lambda。
- fun html(init: HTML.() -> Unit): HTML { // <-- only this changed
- val html = HTML()
- init(html)
- return html
- }
复制代码
请参阅如何像以前一样将 html 作为参数传递给 init?
当然,我们也可以这样调用它:html.init(),如示例所示。 HTML 的实例在 lambda 块内变成了 this。
现在,我们可以这样做:
由于可以省略,因此我们在这里:
所以最终 lambdas 和接收器使代码更简洁,并允许我们使用良好的生成器语法。
|