【问题标题】:Swift 3 errors with additional data带有附加数据的 Swift 3 错误
【发布时间】:2017-05-03 08:10:40
【问题描述】:

在 Swift 3 中,将(可能很多)附加信息放入错误/异常中以供捕获器用来解决/处理问题的推荐方法是什么?在我看到的所有示例中,他们使用带有关联值的 enums,对于大量信息而言,这似乎过于繁琐/冗长。

具体来说,我正在编写一个简单的解析器,并希望有一个地方来存储受影响的行号和列号(以及将来可能的其他信息),但不需要每个处理程序都将它们显式声明为关联值,因为那将是调用者的负担。

在这一点上,我基本上可以看到两种方法,看起来都不是特别优雅,而且都需要定义两个不同的东西:

  1. 定义一个表示错误类型的外部enum 错误,并为每种情况接受一个参数,该参数是一个包含其他异常详细信息的对象,或者
  2. 将该对象用作实际的Error,并将enum 中的一个case 传递给它的构造函数以表示实际的错误情况。

这两个对我来说都有些不干净,因为它们使用两个独立的概念来表示一个简单的想法,一个错误,我只是想知道是否有更好的方法来做到这一点。

是否有任何约定或推荐的方法来处理可能需要包含大量附加信息的错误?

【问题讨论】:

  • 我不确定我是否正确理解了你的问题,一个具体的例子可能会有所帮助。 – 但请注意 1) enum 可以有关联值,2) 错误可以是 structclass(带有属性),它不必是 enum
  • 我想如果我可以使用一个结构并使用选项2,这与更传统的异常对象基本相同,如果我在该结构内定义枚举它不会太难看.
  • 具体来说,我正在编写一个简单的解析器,并希望有一个地方来存储受影响的行号和列号(以及未来可能的其他信息),但不需要每个处理程序都明确地将它们添加为关联值。
  • “可能有很多附加信息” 是什么意思?一组固定的属性,或任意信息,如NSError 中的userInfo 字典?
  • 就我而言,这将是一组固定的属性。

标签: swift error-handling swift3


【解决方案1】:

我不知道是否有“推荐”的方式,也许其他人可以 回答这个问题或提供更好的解决方案。

但一种可能的方法是使用struct(带有属性)作为错误类型,并为需要的值使用可选属性 不提供。示例:

struct ParserError: Error {
    enum Reason {
        case invalidCharacter
        case unexpectedEOF
    }
    let reason: Reason
    let line: Int?
    let column: Int?

    init(reason: Reason, line: Int? = nil, column: Int? = nil) {
        self.reason = reason
        self.line = line
        self.column = column
    }
}

可能还想采用LocalizedError 协议来 提供合理的错误描述,即使 捕手不知道具体的错误类型(比较How to provide a localized description with an Error type in Swift?):

extension ParserError: LocalizedError {
    public var errorDescription: String? {
        var description: String
        switch reason {
        case .invalidCharacter:
            description = "Invalid Character in input file"
        case .unexpectedEOF:
            description = "Unexpected end of file"
        }
        if let line = line {
            description += ", line \(line)"
        }
        if let column = column {
            description += ", column \(column)"
        }
        return description
    }
}

使用示例:

func parse() throws {
    // Throw error with line number, but without column:
    throw ParserError(reason: .invalidCharacter, line: 13)
}

do {
    try parse()
} catch let error {
    print(error.localizedDescription)
}

输出:

输入文件中的无效字符,第 13 行

【讨论】:

  • 这就是我要找的,谢谢!也感谢LocalizedError 的提示。
猜你喜欢
  • 2016-03-14
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 2013-06-10
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
相关资源
最近更新 更多