title |
---|
Swift 之 Error |
Table of Contents
我们大家都知道 NSError
在 Swift 中有的新的类型 - Error
首先我们来看 Error 的定义
public protocol Error
惊不惊喜, 意不意外. 它是一个协议. 没错! 就是它, 协议在 Swift 中可以算是非常重要的, 它可以以任意的形式表述 Error, 🌰走你
你可以这样
enum YourOwnError: Error {
case waller
case hacker
case j6me
}
enum YourOwnError: Int, Error {
case waller = 4
case hacker = 44
case J6me = 666
}
或者这样
struct YourOwnError: Error {
enum Kind {
case waller
case hacker
case j6me
}
let code: Int
let kind: Kind
}
再或者这样 (一般使用 enum 和 struct 居多)
class YourOwnError: Error {
enum Kind {
case waller
case hacker
case j6me
}
let code: Int
let kind: Kind
init...
}
怎么定义我们了解了, 那么问题来了.
仅用作预定义好的错误类型, 信息都是提前预设好的, 当然在编码阶段可以随时扩展 extension
大法, 走你
可以在使用时创建自定义错误类型, 上面的例子中有介绍.
这时候就要使用其他的协议来帮助我们了.
/// Describes an error that provides localized messages describing why
/// an error occurred and provides more information about the error.
public protocol LocalizedError : Error {
/// A localized message describing what error occurred.
var errorDescription: String? { get }
/// A localized message describing the reason for the failure.
var failureReason: String? { get }
/// A localized message describing how one might recover from the failure.
var recoverySuggestion: String? { get }
/// A localized message providing "help" text if the user requests help.
var helpAnchor: String? { get }
}
看到这个东西是不是仿佛看到了 NSError
的影子. 没错. Error
拆分了 NSError
的各项职能, 变得更加灵活和更加容易表述.
还有一个需要注意的地方就是 Error 的表述一般使用 error.localizedDescription
, 这里调用的就是 LocalizedError
的 errorDescription
属性, 而并不是简单的 override var localizedDescription
这个是打印字符串的标准协议了. 不多赘述.
public protocol CustomStringConvertible {
/// A textual representation of this instance.
///
/// Calling this property directly is discouraged. Instead, convert an
/// instance of any type to a string by using the `String(describing:)`
/// initializer. This initializer works with any type, and uses the custom
/// `description` property for types that conform to
/// `CustomStringConvertible`:
///
/// struct Point: CustomStringConvertible {
/// let x: Int, y: Int
///
/// var description: String {
/// return "(\(x), \(y))"
/// }
/// }
///
/// let p = Point(x: 21, y: 30)
/// let s = String(describing: p)
/// print(s)
/// // Prints "(21, 30)"
///
/// The conversion of `p` to a string in the assignment to `s` uses the
/// `Point` type's `description` property.
var description: String { get }
}
public protocol CustomDebugStringConvertible {
/// A textual representation of this instance, suitable for debugging.
///
/// Calling this property directly is discouraged. Instead, convert an
/// instance of any type to a string by using the `String(reflecting:)`
/// initializer. This initializer works with any type, and uses the custom
/// `debugDescription` property for types that conform to
/// `CustomDebugStringConvertible`:
///
/// struct Point: CustomDebugStringConvertible {
/// let x: Int, y: Int
///
/// var debugDescription: String {
/// return "(\(x), \(y))"
/// }
/// }
///
/// let p = Point(x: 21, y: 30)
/// let s = String(reflecting: p)
/// print(s)
/// // Prints "(21, 30)"
///
/// The conversion of `p` to a string in the assignment to `s` uses the
/// `Point` type's `debugDescription` property.
var debugDescription: String { get }
}
好了. 以上就是我个人的一些使用经验之谈.