Бросок из конечного закрытия в Swift - PullRequest
0 голосов
/ 19 июня 2020

Я занимаюсь сетевым подключением и хочу выйти из конечного закрытия в соответствии с ответом.

В результате я обнаружил, что не могу сделать это с «недопустимым преобразованием» ошибка.

Я свел проблему к минимальному примеру - клише не допускаются:

func innerClosure(a: String, completion: (String)->Void) {
    completion(a + ", World")
}

func iCanThrow(name: String, closure: (String,(String)->Void)->(Void) ) throws {
     closure(name, {response in
        print (response)
        if response == "Hello, World" {
            throw ClicheError.cliche
        }
    })

}

try iCanThrow(name: "Hello", closure: innerClosure)

Объявление, которое вы видите, я хочу выбросить ClicheError из конечного закрытия - но специфика c ошибка - Invalid conversion from throwing function of type '(String) throws -> Void' to non-throwing function type '(String) -> Void'

Я пробовал использовать различные комбинации throws и rethrows, но я просто не могу заставить это работать - даже если я получаю внутреннее закрытие на throw я получаю следующее:

enum ClicheError: Error {
    case cliche
    case latecliche
}

func innerClosure(a: String, completion: (String) throws ->Void) {
    try? completion(a + ", World")
}

func iCanThrow(name: String, closure: (String,(String) throws ->Void) throws ->(Void) ) throws {
     try closure(name, {response in
        print (response)
        if response == "Hello, World" {
            throw ClicheError.cliche
        }
    })

}

try iCanThrow(name: "Hello", closure: innerClosure)

Что компилирует, выбрасывает, но на самом деле не выбрасывает из iCanThrow - то есть я не могу выбросить!

1 Ответ

4 голосов
/ 19 июня 2020
func innerClosure(a: String, completion: (String) throws ->Void) {
    try? completion(a + ", World")
}

не вызывает ошибку, потому что try? является «необязательной попыткой»: он возвращает Optional, который равен nil в случае ошибки. Здесь возвращаемое значение игнорируется, поэтому ошибки игнорируются без уведомления.

Вам нужно

func innerClosure(a: String, completion: (String) throws ->Void) rethrows {
    try completion(a + ", World")
}

, что делает innerClosure() функцией выброса, только если она вызывается с параметром выброса.

func iCanThrow() также можно пометить как rethrows вместо throws, потому что он не выдает ошибку «сам по себе». См. Также В чем разница между бросками и повторными бросками в Swift? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...