如何在使用Ktor的HTML构建器时将部分代码提取到Kotlin的局部变量中?
问题描述:
我想了解Kotlin/Ktor中的HTML生成器。 的example here使用HTML生成器生成的结果:如何在使用Ktor的HTML构建器时将部分代码提取到Kotlin的局部变量中?
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)
。
为什么它不起作用,当我只是试图提取身体变量?
答
我认为编译器不喜欢在默认参数之后有一个强制的,除非它是大括号外的lambda。
尝试将其命名为:
call.respondHtml(block = block)
答
顺便说一句,如果你想要的是提取的逻辑,我会建议使用的功能。对于你的例子:
fun HTML.headAndBody() {
head {
title { +"HTML Application" }
}
body {
h1 { +"Sample application with HTML builders" }
widget {
+"Widgets are just functions"
}
}
}
call.respondHtml {
headAndBody()
}
这样,你甚至可以将参数添加到您的HTML块,创建一个自定义组件出来。
使用命名参数不能解决它,但解释是有道理的。 – peq