一个示例代码
如下示例代码,实现了一个简单的对象转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?:返回的是一个可选类型
- 成功:返回具体的值;
- 失败:就是出现错误了,但具体哪类错误,我们并不关注,统一返回了一个 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 {
    
}
PREVIOUSSwift 内存管理
NEXTSwift Mirror