让我来说明为什么我认为这不是How to provide a localized description with an Error type in Swift?
的重复提供的答案仍然会导致一些静态/类函数调用,而不是初始化器样式或需要转换为NSError(我想避免)。
简要总结原因:
throws
未声明错误类型的Swift函数。我们无法强制catch
传递一个简单符合Error
协议的自定义类型。知道,在do-catch方面,我们没有得到编译器的帮助,因为我们得到了什么类型(如果是自定义的)错误,默认情况下我们期望已知的NSError
属性。否则,我们需要简单地依赖文本文档来解释我们可以捕获的错误类型,因为catch只会传递Error
类型。
现在,与NSError不同,Error是一种协议,我们在userInfo
中获取的属性是只读的。因此我们求助于构造NSError类型,并将其转换为Error。
我正在尝试创建一个简单的clean结构,它返回一个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:...
,而不是静态函数。
Swifty方式更像是:
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属性。
答案 0 :(得分:6)
与How to provide a localized description with an Error type in 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)
}
这将打印给定消息的本地化版本。
请注意,catch子句中的error
是一般Error
,所以
调用者不需要将其强制转换为具体的错误类型(甚至知道
抛出了哪种错误类型。)
答案 1 :(得分:4)
Error
是一个协议,您可以抛出任何符合该协议的内容
例如
struct MYError : Error {
let description : String
let domain : String
var localizedDescription: String {
return NSLocalizedString(description, comment: "")
}
}
你可以使用它:
func test() throws
{
throw MYError(description: "Some Error has happened", domain: "com.somthing.error")
}
do {
try test()
} catch let error as MYError{
print("error: ", error.domain, error.localizedDescription)
}
答案 2 :(得分:2)
终于找到了一种在通用错误类型中粘贴任何东西的方法。 感谢 vadian 和 Martin R ,我最终得到了答案。
归结为:
struct MyError: Error {
var locString: String
var reason: String?
var code: Int
var wish: String
}
// The errorDescription is the only part that actually comes generically with Error
extension MyError: LocalizedError {
// This is actually part of LocalizedError
var errorDescription: String? {
return locString
}
}
extension Error {
var errorCode: Int {
return (self as! MyError).code
}
var failureReason: String? {
return (self as! MyError).reason
}
var everythingYouWishFor: String {
return (self as! MyError).wish
}
}
...
throw MyError(locString: "Localized string", reason: "The reason", code: 12, wish: "Best wishes")