假设我有一个班级。 如果我的班级没有遵循所描述的规则
,我想在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
内的条件逻辑。
我最初的想法可能是错的,但如果你帮助我做得更好,我将不胜感激。
答案 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
}
}