Как передать функцию в другую функцию, которая устанавливает закрытие завершения? - PullRequest
0 голосов
/ 13 февраля 2020

Предполагая, что у нас есть следующий метод:

func searchLocation(keyword: String, completion: @escaping RequestResult<[Location])>)

, где RequestResult - это typealias для public typealias RequestResult<T> = (Result<T>) -> ()

и другой метод:

func throttleRequest<T>(request: PLACEHOLDER, completion: @escaping RequestResult<[T]> {
    request { result in 
        print("Capturing some data") // do some stuff with the result in this scope
        completion(result)           // tell the caller the network function finsihed with `result`
    }
}

How я должен изменить сигнатуры метода, чтобы я мог сделать что-то вроде этого:

throttleRequest(request: {
    searchLocation(keyword: "New York", completion: PLACEHOLDER)
}, 
completion: { result in
    if case .success(let found) = result {
       print("location found")
    }
})

, чтобы напечатать следующее:

$ Location found
$ Capturing some data

Я ввел PLACEHOLDER выше для некоторых определений типов, так как я не могу понять, что правильно.

1 Ответ

0 голосов
/ 13 февраля 2020

Во-первых, давайте использовать правильный тип возврата вместо (), который совпадает с Void. Это легче читать, когда вы явно указываете, что возвращаете void вместо того, чтобы писать (). В любом случае вам нужен параметр лямбда-функции.

IE: вам нужна функция, которая принимает лямбду в качестве аргумента. Следовательно:

public typealias RequestResult<T> = (Result<T, Error>) -> Void

func searchLocation(keyword: String, completion: RequestResult<[Location]>) {
    completion(.success([Location()]))
}

func throttleRequest<T>(request: (RequestResult<[T]>) -> Void, completion: @escaping RequestResult<[T]>) {
    request {
        print("Capturing some data")
        completion($0)
    }
}

Таким образом, синтаксис функции / лямбды в качестве параметра: (ArgumentType...) -> ReturnType

  • (Int) -> Void - это функция, которая принимает int, возвращает Void / Ничего.
  • (T) -> U - это функция, которая принимает аргумент T и возвращает U.

Аналогично, если вы хотите, чтобы параметр был необязательным, то он определяется как:

((Arguments...) -> ReturnType)?

Использование:

throttleRequest(request: { result in
        self.searchLocation(keyword: "New York", completion: result)
    }, completion: { result in
        switch result {
        case .success(let locations):
            print(locations)

        case .failure(let error):
            print(error)
        }
    })

Или проще для чтения (например, вы задаете _ request параметр):

throttleRequest({ self.searchLocation(keyword: "New York", completion: $0) }) {
        switch $0 {
        case .success(let locations):
            print(locations)

        case .failure(let error):
            print(error)
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...