Swift try

 

一个示例代码

如下示例代码,实现了一个简单的对象转Map:

protocol JsonMap {
    func jsonMap() -> Any
}

extension JsonMap {
    func jsonMap() -> Any {
        let mirror = Mirror(reflecting: self);
        guard !mirror.children.isEmpty else { return self }
        
        var reslut: [String : Any] = [:]
        
        for (key, value) in mirror.children {
            if let v = value as? JsonMap {
                if let k = key {
                    reslut[k] = v.jsonMap()
                } else {
                    print("NO key")
                }
            } else {
                print("value not conform protocal")
            }
        }
        return reslut
    }
}

extension Int: JsonMap {}
extension String: JsonMap {}
class Dog: JsonMap {
    var age = 2
    var name = "naonao"
    deinit {
        print("Dog release ...")
    }
}


var d = Dog()
print(d.jsonMap())
// ["name": "naonao", "age": 2]

但是其中的错误并没有处理。

添加错误处理

我们定义一个枚举来表示错误的类型:

enum JsonMapError: Error {
    case emptyKey
    case notConfirmProtocal
}

想让调用者明显的感受的错误,可以使用 throw 关键字,如下示例代码,注意 throw 的使用方法:

enum JsonMapError: Error {
    case emptyKey
    case notConfirmProtocal
}

protocol JsonMap {
    func jsonMap() throws -> Any
}

extension JsonMap {
    func jsonMap() throws -> Any {
        let mirror = Mirror(reflecting: self);
        guard !mirror.children.isEmpty else { return self }
        
        var reslut: [String : Any] = [:]
        
        for (key, value) in mirror.children {
            if let v = value as? JsonMap {
                if let k = key {
                    reslut[k] = try v.jsonMap()
                } else {
                    throw JsonMapError.emptyKey
                }
            } else {
                throw JsonMapError.notConfirmProtocal
            }
        }
        return reslut
    }
}

extension Int: JsonMap {}
extension String: JsonMap {}

class Dog: JsonMap {
    var age = 2
    var name = "naonao"
    deinit {
        print("Dog release ...")
    }
}

var d = Dog()
print(try?d.jsonMap())

Swift 的几种错误处理方式

① try

如下示例代码:

reslut[k] = try v.jsonMap()

代表自己不会处理错误,会甩给上层的函数处理。

② try? 和 try!

try?:返回的是一个可选类型

  1. 成功:返回具体的值;
  2. 失败:就是出现错误了,但具体哪类错误,我们并不关注,统一返回了一个 nil,这样错误不会向上抛。

try!:写这句的时候,你必须迷之自信,绝对不会发生错误,否则就是 crash

③ do … catch

我们可以实现一个具体的描述:

extension JsonMapError: LocalizedError {
    var errorDescription: String? {
        switch self {
        case .emptyKey:
            return NSLocalizedString("emptyKey", comment: "key is empty")
        case .notConfirmProtocal:
            return NSLocalizedString("notConfirmProtocal", comment: "class is not confirm protocol")
        }
    }
    
    var recoverySuggestion: String? {
        switch self {
        case .emptyKey:
            return "the instance key is null"
        case .notConfirmProtocal:
            return "check class confirm protocol of JsonMap"
        }
    }
}

var d = Dog()
do {
    let m = try d.jsonMap()
    print(m)
} catch {
    print((error as? LocalizedError)?.errorDescription ?? nil)
}

也可以进行具体的类型匹配:

var d = Dog()
do {
    let m = try d.jsonMap()
    print(m)
} catch JsonMapError.emptyKey {
    
} catch JsonMapError.notConfirmProtocal {
    
} catch {
    
}