Swift Catch Pattern, который связывает ошибку с переменной - PullRequest
0 голосов
/ 02 января 2019

Использование Swift 4.2 и XCode 10

В Swift 4.2 DecodingError является перечислением.Есть (в настоящее время) четыре разных случая.Я могу отлавливать каждый случай отдельно и связывать переменные, которые я могу использовать для регистрации ошибки, как показано в следующем коде ...

do {
    let model = try jsonDecoder.decode(BattleShip.self, from: jsonData!)
    print(model)
} catch DecodingError.dataCorrupted(let context) {
    print(context.debugDescription)
} catch DecodingError.keyNotFound(let key, let context) {
    print("\(key.stringValue) was not found, \(context.debugDescription)")
} catch DecodingError.typeMismatch(let type, let context) {
    print("\(type) was expected, \(context.debugDescription)")
} catch DecodingError.valueNotFound(let type, let context) {
    print("no value was found for \(type), \(context.debugDescription)")
} catch {
    print("I know not this error")
}

Но это большой код, который можно поместить везде, где я могу столкнуться с декодированиемошибка.И, если мой блок do {} имеет несколько вызовов, которые выдают, мне, возможно, придется обрабатывать ошибки, которые эти методы вызывают по-разному.Шаблон, который я пытаюсь реализовать, выглядит следующим образом ... где decodingError (error) содержит весь беспорядочный код выше

do {
    let object1 = try decoder.decode(SomeClass.self, from: someData)
    try object2.methodThatThrowsSomeOtherError()
} catch <all decoding errors> {      // this is invalid pseudocode
    MyCentralLogger.log.decodingError(error)
} catch let nonDecodingError {
    MyCentralLogger.log.error(nonDecodingError)
}

У меня может быть шаблон перехвата, подобный этому, который, кажется, удовлетворяет всем перечислениямслучаи (по крайней мере, он компилируется)

} catch is DecodingError {

, но, похоже, компилятор не выполняет автоматическую привязку переменной 'error', и я не вижу никакой опции, например

} catch let decodingError is DecodingError {  // THIS IS NOT VALID

ЕслиЯ просто улавливаю все ошибки, у меня легко может быть переключатель в центральном методе, который соответствующим образом разделяет различные случаи ошибок декодирования.Но я хочу быть в состоянии избежать отправки ошибок не декодирования в этот коммутатор.Я также могу отделить свои блоки do {}, чтобы выполнять в нем только этапы декодирования, но это также усложняет код, особенно если вы декодируете несколько сообщений, перемежающихся с другими действиями.

Предложения?Спасибо всем!

1 Ответ

0 голосов
/ 02 января 2019

Синтаксис, используемый в строке catch, является точно таким же синтаксисом шаблона, который используется в case switch. Если вы знаете, как написать case, вы знаете, как написать catch.

Так, например, вы жалуетесь:

} catch let decodingError is DecodingError {  // THIS IS NOT VALID

правый. Но это является действительным:

} catch let decodingError as DecodingError { 

О, какая разница в одной букве.

...