假设我有一个类。如果我的班级不遵循所述规则
,我想在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
和Crumperer中的描述,我会遇到错误。但是我想要的是跳过创建此实例而不执行错误。我想继续检查 init
中的条件逻辑。
我最初的想法可能是错误的,但是如果您帮助我更正确地使它变得更加正确。
您可以使用可失败的初始分散器来实现此目的,如果您不满足您的支票,则您的对象将为零。
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)!
}
}
我不同意@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
}
}