3

我正在尝试了解 Kotlin / Ktor 中的 HTML 构建器。此处的示例使用 HTML 构建器来构建结果:

call.respondHtml {
    head {
        title { +"HTML Application" }
    }
    body {
        h1 { +"Sample application with HTML builders" }
        widget {
            +"Widgets are just functions"
        }
    }
}

我正在尝试将主体提取到这样的变量中:

val block: HTML.() -> Unit = {
    head {
        title { +"HTML Application" }
    }
    body {
        h1 { +"Sample application with HTML builders" }
    }
}
call.respondHtml(block)

现在我得到以下编译错误:

Error:(37, 22) Kotlin: None of the following functions can be called with the arguments supplied: 
public suspend fun ApplicationCall.respondHtml(status: HttpStatusCode = ..., versions: List<Version> = ..., cacheControl: CacheControl? = ..., block: HTML.() -> Unit): Unit defined in org.jetbrains.ktor.html
public suspend fun ApplicationCall.respondHtml(status: HttpStatusCode = ..., block: HTML.() -> Unit): Unit defined in org.jetbrains.ktor.html

当我添加第一个(可选)参数时,它再次起作用:call.respondHtml(HttpStatusCode.OK, block).

当我只是尝试将主体提取到变量中时,为什么它不起作用?

4

2 回答 2

3

顺便说一句,如果您想要提取逻辑,我建议您使用函数。对于您的示例:

fun HTML.headAndBody() {
    head {
        title { +"HTML Application" }
    }
    body {
        h1 { +"Sample application with HTML builders" }
        widget {
            +"Widgets are just functions"
        }
    }
}

call.respondHtml {
    headAndBody()
}

这样,您甚至可以将参数添加到您的 html 块中,从中创建一个自定义组件。

于 2017-08-11T07:34:38.237 回答
3

我认为编译器不喜欢在默认参数之后强制使用,除非它是大括号之外的 lambda。

尝试命名它:

call.respondHtml(block = block)
于 2017-08-05T13:46:19.340 回答