How do I tell which guard statement failed?

前端 未结 7 1699
醉梦人生
醉梦人生 2020-12-28 17:58

If I’ve got a bunch of chained guard let statements, how can I diagnose which condition failed, short of breaking apart my guard let into multiple statements?

Given

7条回答
  •  旧巷少年郎
    2020-12-28 18:51

    I think other answers here are better, but another approach is to define functions like this:

    func checkAll(clauses: (T1?, T2?, T3?)) -> (T1, T2, T3)? {
        guard let one = clauses.0 else {
            print("1st clause is nil")
            return nil
        }
    
        guard let two = clauses.1 else {
            print("2nd clause is nil")
            return nil
        }
    
        guard let three = clauses.2 else {
            print("3rd clause is nil")
            return nil
        }
    
        return (one, two, three)
    }
    

    And then use it like this

    let a: Int? = 0
    let b: Int? = nil
    let c: Int? = 3
    
    guard let (d, e, f) = checkAll((a, b, c)) else {
        fatalError()
    }
    
    print("a: \(d)")
    print("b: \(e)")
    print("c: \(f)")
    

    You could extend it to print the file & line number of the guard statement like other answers.

    On the plus side, there isn't too much clutter at the call site, and you only get output for the failing cases. But since it uses tuples and you can't write a function that operates on arbitrary tuples, you would have to define a similar method for one parameter, two parameters etc up to some arity. It also breaks the visual relation between the clause and the variable it's being bound to, especially if the unwrapped clauses are long.

提交回复
热议问题