使用assert处理错误

时间:2017-12-14 14:00:20

标签: ios swift error-handling

假设我有一个班级。 如果我的班级没有遵循所描述的规则

,我想在init中给出错误
class Puzzle {

var puzzle_array: [Int]
var zero_index: Int

public init(array: [Int]) {
    assert(array.count == 9, "Array should be lenght 9")
    assert(array.index(of: 0) != nil, "There should ne 0 in array")
    puzzle_array = array
    zero_index = puzzle_array.index(of: 0)!
}
}

然后我需要在循环中创建这个类的几个实例。其中一些,不满足条件,我在init和编译器中描述,我将得到一个错误。 但我想要的是跳过创建这个实例而不执行错误。我想继续检查init内的条件逻辑。

我最初的想法可能是错的,但如果你帮助我做得更好,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

您可以使用failable initialiser来完成此操作,如果您不满意,您的对象将为零。

class Puzzle {
  var puzzle_array: [Int]
  var zero_index: Int

  public init?(array: [Int]) {
    guard array.count == 9, array.index(of: 0) != nil else {
      return nil
    }

    puzzle_array = array
    zero_index = puzzle_array.index(of: 0)!
  }
}

答案 1 :(得分:1)

我不同意@colmg您应该使用failable initialiser,因为它会破坏有关实际出错的信息。

相反,您应该使用throwable initalizer

class Puzzle {
    var puzzle_array: [Int]
    var zero_index: Int

    public init(array: [Int]) throws {
        try assert(array.count == 9, "Array should be lenght 9")
        try assert(array.index(of: 0) != nil, "There should ne 0 in array")
        puzzle_array = array
        zero_index = puzzle_array.index(of: 0)!
    }
}

假设此处assert不是标准版本,但此函数:

struct AssertError: Error {
    let description: String
}

func assert(_ condition: @autoclosure () -> Bool, _ description: String) throws {
    if !condition() {
        throw AssertError(description: description)
    }
}

现在你可以这样做:

do {
   let puzzle = try Puzzle([0, 1, 2, 3, 4])
} catch let error {
   // Here you can handle error, and see what exactly went wrong, instead of just knowing that initialisation failed
}

或者您可以使用更高级的版本:

func assert(_ condition: @autoclosure () -> Bool, _ error: Error) throws {
    if !condition() {
        throw error
    }
}

class Puzzle {
    var puzzle_array: [Int]
    var zero_index: Int

    public init(array: [Int]) throws {
        try assert(array.count == 9, PuzzleError.invalidArrayLength)
        try assert(array.index(of: 0) != nil, PuzzleError.arrayContainsZero)
        puzzle_array = array
        zero_index = puzzle_array.index(of: 0)!
    }

    enum PuzzleError: Error {
        case invalidArrayLength
        case noZeroInArray
    }
}