2017-08-05 42 views
3

我想了解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)

为什么它不起作用,当我只是试图提取身体变量?

回答

3

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

尝试将其命名为:

call.respondHtml(block = block) 
+0

使用命名参数不能解决它,但解释是有道理的。 – peq

2

顺便说一句,如果你想要的是提取的逻辑,我会建议使用的功能。对于你的例子:

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

call.respondHtml { 
    headAndBody() 
} 

这样,你甚至可以将参数添加到您的HTML块,创建一个自定义组件出来。

相关问题