自定义错误类型初始化程序

bau*_*sic 3 swift

让我加上为什么我认为这不是重复如何在Swift中提供具有错误类型的本地化描述?

提供的答案仍然会导致一些静态/类函数调用,而不是初始化器样式或需要转换为NSError(我想避免).


简要总结一下原因:

一个throws不声明错误类型的 Swift函数.我们无法强制catch传递一个简单符合Error协议的自定义类型.知道在do-catch方面,我们没有得到编译器的帮助,因为我们得到了什么类型(如果是自定义的)错误,默认情况下我们会期望已知的NSError属性.否则,我们需要简单地依赖文本文档来解释我们可以捕获的错误类型,因为catch只会传递一个Error类型.

现在,与NSError不同,Error是一种协议,其中我们获取的属性userInfo是只读的.所以我们求助于构造NSError类型,并将其转换为Error.


我试图创建一个简单的干净结构,返回一个错误类型(而不是NSError),我可以抛出:

throw MYError(domain: "com.somthing.error", code: 0, userInfo: [NSLocalizedDescriptionKey : "Something bad happened"])
Run Code Online (Sandbox Code Playgroud)

主要问题是设置的唯一方法NSLocalizedDescriptionKey是初始化NSError对象.这样做需要转换为Error类型(这是我试图避免的).

我首先尝试使用extension Error {...,但不能使用初始化程序.

如果我使用符合Error protocol(struct MyError: Error {...)的结构,我仍然localizedDescription只有get 的问题.

我使用的实际上是这样的:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用如下:

throw MYError.with(localizedDescription: "Some Error has happened")
Run Code Online (Sandbox Code Playgroud)

直觉上,我希望类型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)")
}
Run Code Online (Sandbox Code Playgroud)

目前尚不清楚我们是否还在那里.似乎NSError仍在发挥作用,我知道我可以期望得到一个localizedDescription可选的localizedFailureReason和熟悉的NSError属性.

Mar*_*n R 8

与如何在Swift中提供具有错误类型的本地化描述类似 您可以定义采用LocalizedError 协议的自定义错误类型 :

public struct MyError: Error {
    let msg: String

}

extension MyError: LocalizedError {
    public var errorDescription: String? {
            return NSLocalizedString(msg, comment: "")
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

do {
    throw MyError(msg: "Something happened")
} catch let error {
    print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)

这将打印给定消息的本地化版本.请注意,errorcatch-clause是一般的Error,因此调用者不需要将其强制转换为具体的错误类型(甚至知道抛出了哪种错误类型).


vad*_*ian 7

Error是一个协议,你可以抛出任何符合该协议的东西

例如

struct MYError : Error {
    let description : String
    let domain : String

    var localizedDescription: String {
        return NSLocalizedString(description, comment: "")
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以使用它:

func test() throws
{
  throw MYError(description: "Some Error has happened", domain: "com.somthing.error")
}
Run Code Online (Sandbox Code Playgroud)
do {
    try test()
} catch let error as MYError{
    print("error: ", error.domain, error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)