让我在前面加上为什么我认为这与“如何在Swift中提供带有错误类型的本地化描述”不重复的原因开头。
提供的答案仍将导致某些静态/类函数调用,而不是初始化器样式,或者需要强制转换为NSError(我想避免)。
简要总结一下原因:
throws
没有声明错误类型的Swift函数。我们不能强制catch
传递简单符合Error
协议的自定义类型。知道,在do-catch方面,编译器无法提供有关所得到的错误类型(如果是自定义)的帮助,默认情况下,我们将期望已知的NSError
属性。否则,我们只需要依靠文本文档来说明我们可以捕获的错误的类型,因为捕获只会传递一个Error
类型。
现在,与NSError不同,Error是一个协议,其中我们获取的属性userInfo
是只读的。因此,我们求助于构造一个NSError类型,并将其强制转换为Error。
我正在尝试创建一个简单的干净结构,该结构返回一个Error类型(不是NSError),可以在其中抛出:
throw MYError(domain: "com.somthing.error", code: 0, userInfo: [NSLocalizedDescriptionKey : "Something bad happened"])
主要问题是,设置的唯一方法NSLocalizedDescriptionKey
是初始化NSError对象。这样做将需要强制Error
类型转换(这是我要避免的事情)。
我首先尝试使用extension Error {...
,但无法使用初始化程序。
如果我使用符合错误协议(struct MyError: Error {...
)的结构,我仍然会localizedDescription
遇到问题。
我使用的实际上是这样的:
struct MYError: Error {
static func with(domain: String = "com.somthing.error", code: Int = 0, localizedDescription: String) -> Error {
return NSError(domain: domain, code: code, userInfo: [NSLocalizedDescriptionKey : localizedDescription]) as Error
}
}
我可以这样使用:
throw MYError.with(localizedDescription: "Some Error has happened")
凭直觉,我希望类型MYError
只使用一个初始化器MYError(domain:...
,而不是静态函数。
更快捷的方式是:
enum ErrorType: Error {
case one
case two
case three(with: String)
}
...
// In some function:
throw ErrorThrown.three(with: "Three!")
...
// Catch like:
catch ErrorType.three(let str) {
print("Error three: \(str)")
}
尚不清楚我们是否在那里。看来NSError仍然发挥着作用,我知道我可以期望得到一个localizedDescription
可选的localizedFailureReason
和熟悉的NSError属性。
与如何在Swift中提供带有错误类型的本地化描述类似?您可以定义采用LocalizedError
协议的自定义错误类型:
public struct MyError: Error {
let msg: String
}
extension MyError: LocalizedError {
public var errorDescription: String? {
return NSLocalizedString(msg, comment: "")
}
}
例:
do {
throw MyError(msg: "Something happened")
} catch let error {
print(error.localizedDescription)
}
这将打印给定消息的本地化版本。请注意,error
在catch子句中是一个general Error
,因此调用方不需要将其强制转换为具体的错误类型(甚至不需要知道抛出哪种错误类型)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句