如何理解这段 GCDWebServer swift 单元测试代码?
How to understand this GCDWebServer swift unit test code?
我遇到过这段代码:
class WebServerTests: XCTestCase {
let webServer: GCDWebServer = GCDWebServer()
var webServerBase: String!
/// Setup a basic web server that binds to a random port and that has one default handler on /hello
private func setupWebServer() {
webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self) { (request) -> GCDWebServerResponse! in
return GCDWebServerDataResponse(HTML: "<html><body><p>Hello World</p></body></html>")
}
我对 webServer.addHandlerForMethod
部分感到困惑。在我看来它已经是一个完整的函数调用(webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self)
)。因此我不明白为什么它后面跟着一个闭包( {(request) -> ...
)
编辑:澄清我不明白的地方
根据https://github.com/swisspol/GCDWebServer上的文档,obj-c中的函数签名是:
[webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
因此我希望它的 swift 对应物会像这样被调用:
webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self, { (request) -> GCDWebServerResponse! in
return GCDWebServerDataResponse(HTML: "<html><body><p>Hello World</p></body></html>")
})
即传入请求的处理作为第三个参数传递。但是由于闭包出现在结束')'之后,它看起来根本不像是函数调用的一部分。
为什么函数签名以这种方式从 obj-c 映射到 swift?
闭包是处理传入请求的地方。当请求 /hello
路径的 GET
方法出现时,它告诉服务器 运行 闭包代码。
在您发布的代码中,闭包中的代码创建了服务器 returns.
的响应
在 Swift 中,如果函数的最后一个参数是闭包,则可以使用此语法。这是 Swift language guide section about closures 中的示例(向下滚动到 尾随闭包 ):
func someFunctionThatTakesAClosure(closure: () -> ()) {
// function body goes here
}
// here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure({
// closure's body goes here
})
// here's how you call this function with a trailing closure instead:
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
然后还有这张便条:
If a closure expression is provided as the function’s only argument and you provide that expression as a trailing closure, you do not need to write a pair of parentheses () after the function’s name when you call the function.
这意味着这样写也是合法的:
someFunctionThatTakesAClosure {
// closure body
}
… 这有助于提供良好的元编程语法。例如:
let lock = NSLock()
func locked(closure: () -> ()) {
lock.lock();
closure()
lock.unlock();
}
locked {
NSLog("Hello, world!")
}
我遇到过这段代码:
class WebServerTests: XCTestCase {
let webServer: GCDWebServer = GCDWebServer()
var webServerBase: String!
/// Setup a basic web server that binds to a random port and that has one default handler on /hello
private func setupWebServer() {
webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self) { (request) -> GCDWebServerResponse! in
return GCDWebServerDataResponse(HTML: "<html><body><p>Hello World</p></body></html>")
}
我对 webServer.addHandlerForMethod
部分感到困惑。在我看来它已经是一个完整的函数调用(webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self)
)。因此我不明白为什么它后面跟着一个闭包( {(request) -> ...
)
编辑:澄清我不明白的地方
根据https://github.com/swisspol/GCDWebServer上的文档,obj-c中的函数签名是:
[webServer addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(GCDWebServerRequest* request, GCDWebServerCompletionBlock completionBlock) {
因此我希望它的 swift 对应物会像这样被调用:
webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self, { (request) -> GCDWebServerResponse! in
return GCDWebServerDataResponse(HTML: "<html><body><p>Hello World</p></body></html>")
})
即传入请求的处理作为第三个参数传递。但是由于闭包出现在结束')'之后,它看起来根本不像是函数调用的一部分。
为什么函数签名以这种方式从 obj-c 映射到 swift?
闭包是处理传入请求的地方。当请求 /hello
路径的 GET
方法出现时,它告诉服务器 运行 闭包代码。
在您发布的代码中,闭包中的代码创建了服务器 returns.
的响应在 Swift 中,如果函数的最后一个参数是闭包,则可以使用此语法。这是 Swift language guide section about closures 中的示例(向下滚动到 尾随闭包 ):
func someFunctionThatTakesAClosure(closure: () -> ()) {
// function body goes here
}
// here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure({
// closure's body goes here
})
// here's how you call this function with a trailing closure instead:
someFunctionThatTakesAClosure() {
// trailing closure's body goes here
}
然后还有这张便条:
If a closure expression is provided as the function’s only argument and you provide that expression as a trailing closure, you do not need to write a pair of parentheses () after the function’s name when you call the function.
这意味着这样写也是合法的:
someFunctionThatTakesAClosure {
// closure body
}
… 这有助于提供良好的元编程语法。例如:
let lock = NSLock()
func locked(closure: () -> ()) {
lock.lock();
closure()
lock.unlock();
}
locked {
NSLog("Hello, world!")
}