1

私はこのコードに出くわしました:

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) {

したがって、私はその迅速な対応物が次のように呼び出されることを期待しています:

        webServer.addHandlerForMethod("GET", path: "/hello", requestClass: GCDWebServerRequest.self, { (request) -> GCDWebServerResponse! in
            return GCDWebServerDataResponse(HTML: "<html><body><p>Hello World</p></body></html>")
        })

つまり、着信要求の処理は 3 番目のパラメーターとして渡されます。しかし、クロージャはクロージング ')' の後に来るので、関数呼び出しの一部のようには見えません。

関数シグネチャがobj-cからswiftにこのようにマップされるのはなぜですか?

4

2 に答える 2

1

Swift では、関数の最後の引数がクロージャーの場合、この構文を使用できます。クロージャーに関する Swift 言語ガイド セクションの例を次に示します (下にスクロールしてTrailing 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
}

そして、こんな注意書きも。

クロージャー式が関数の唯一の引数として提供され、その式を末尾クロージャーとして提供する場合、関数を呼び出すときに関数名の後に一対の括弧 () を記述する必要はありません。

これは、次のように書くことも合法であることを意味します。

someFunctionThatTakesAClosure {
    // closure body
}

…これは、優れたメタプログラミング構文を提供するのに役立ちます。例えば:

let lock = NSLock()

func locked(closure: () -> ()) {
    lock.lock();
    closure()
    lock.unlock();
}

locked {
    NSLog("Hello, world!")
}
于 2015-01-21T07:23:32.833 に答える