当lambda作为最后一个参数时,Kotlin函数调用()和{}之间的差异


import io.vertx.core.Vertx
import io.vertx.core.http.HttpMethod
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.CorsHandler
class RestfulServer(
vertx: Vertx,
private val ipAddress: String,
private val port: Int
) {
private val httpServer = vertx.createHttpServer()
private val router: Router = Router.router(vertx)
init {
corsHandling()
createRouter()
}
private fun corsHandling(): Route =
router.route().handler {
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}
private fun createRouter() =
router.get("/").blockingHandler { ctx ->
val response = ctx.response()
response.putHeader("content-type", "application/json")
response.end("""{}""")
}
fun listen() {
httpServer.requestHandler(router).listen(port, ipAddress)
}
fun close() {
httpServer.close()
}
}

当我运行上面的代码时,其余的API调用挂在浏览器中,但如果我注释掉函数corsHandling(),一切都很好。

我发现这不是CorsHandler的问题,而是我如何在kotlin中调用该函数的问题。

工作功能:

private fun corsHandling(): Route =
router.route().handler( // here I use ()
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
)

这个挂起:

private fun corsHandling(): Route =
router.route().handler{ // here I use {}
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}

正如您所看到的,唯一的区别是router.route().handler调用中的{}而不是((。在kotlin中,如果lambda是最后一个参数,则可以省略函数调用。

这个问题可能更多地针对Kotlin而不是Vert.x

它是处理程序的函数定义https://vertx.io/docs/apidocs/io/vertx/ext/web/Route.html#handler-io.vertx.core.Handler-


实际问题是我正在调用处理程序函数,如处理程序({{lambda}}(

@ivo已经有了答案,但只是用一个简单的例子来澄清

fun takesSingleLambda(func: ()-> Unit) {
func()
}
fun main() {
println("1")
takesSingleLambda(
returnsLambda()
)
println("2")
takesSingleLambda{
returnsLambda()
}
println("3, which does exactly the same as 2")
takesSingleLambda({
returnsLambda()
})
}
fun returnsLambda() = { //this is similar to CorsHandler.create("*").allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
println("executing")
}

简单地说:

functionName{
}

与相同

functionName({
})

,而不是

functionName(
)

所以当你写的时候

router.route().handler{
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}

你实际上在写

router.route().handler({
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
})

也就是说,你将一个lambda封装在另一个lambda。当它试图执行处理程序时,它只是创建你希望它处理的处理程序,而不是执行它。我希望这是有意义的。

我将使用Android和Views上的点击监听器的一个例子。

onClick监听器的Java代码

interface OnClickListener {
void onClick(View view)
}
OnClickListener listener = new OnClickListener() {
override void onClick(View view) {
//on click stuff
}
}

在OnClick方法中,您有一个对事件源自的视图的引用。同样的东西可以在Kotlin中使用{}创建。

val listener: OnClickListener = {
// Where is the view reference?
}

它是lambda函数的隐式参数

val listenerExplicit: OnClickListener = { view -> 
// there it is
}

因此,如果你想将其应用于按钮

button.setOnClickListener {
// This is already the inside on the onClick method
}

所以当你有这个:

private fun corsHandling(): Route =
router.route().handler {
CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
}

您创建了一个处理程序{},而该处理程序所做的只是创建CorsHandler并将其丢弃。

这也应该起作用,但只是表明什么没有发生,你想发生什么。

private fun corsHandling(): Route =
router.route().handler { event ->
val fooHandler = CorsHandler
.create("*")
.allowedMethods(mutableSetOf(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.OPTIONS))
fooHandler.handle(event)
}

相关内容

  • 没有找到相关文章

最新更新