If let a = b, a.something () else

I have a piece of code that works, but I'm curious if there is a cleaner way to do the same. I haven't seen anything like it yet.

Logic I want to achieve

  • error

    - nil

    or is notSpecialError

  • error

    non-nil

    BUT .foo()

    returnsfalse

code

enum SpecialError: Error {
    func foo() -> Bool
}

let error: Error? // Some optional Error is passed in

if let myError = error as? SpecialError, myError.foo() {
    // Don't care about this case
} else {
    // This is the case I'm interested in
    bar()
}

      

I'm curious if there is a better way to accomplish this logic if let else

.

+3


source to share


6 answers


The condition you want is an expression, when the expression (error as? SpecialError)?.foo()

evaluates to either:

  • nil

    , in which case error

    it is not SpecialError

    , or is nil

    .
  • false

    , in this case error

    is SpecialError

    but foo()

    returned false

    .

In your case, one way to express this is by taking advantage of the fact that equality operators are overloaded for options and say:



if (error as? SpecialError)?.foo() != true {
    bar()
}

      

Since we are using an overload !=

that compares options true

will advance to Bool?

, so we check what is (error as? SpecialError)?.foo()

not .some(true)

, which in this case is equivalent to checking whether it is .some(false)

or .none

.

+2


source


I may be wrong, but it seems like nothing is happening in the first branch of the instruction if

, and you want to shorten it to the second part? In this case, this should work for you:

if !((error as? SpecialError)?.foo() ?? false) {
    bar()
}

      



This is accomplished bar()

when:
1. error

equal to nil 2. error

does not SpecialError


3. foo()

returns false

+3


source


If I understand your question correctly, you are probably looking for something like this:

if !((error as? SpecialError)?.foo() ?? false) {

+1


source


How to translate it the way you explained it:

if error == nil || !(error! is SpecialError) || !error!.foo() {
    bar()
}

      

Short-circuiting or preventing force reversal is error

a problem.

+1


source


I think your code is hard to read, and John Montgomery's code is even harder to read, and I predict it will be difficult to maintain: Imagine another developer looking at this code a year later and asking you what it does, or what even worse, the developer cannot ask you since you are no longer available. Imagine looking at this code even after a couple of months.

if let myError = error as? SpecialError, myError.foo()

confused, perhaps too smart. It contains too much logic to be read for a long time by the development team.

Your first block can just check if myError is nil

The second block can just check if myError is of type SpecialError

//you could use a guard statement here
if myError == nil {
     return;
}

if let myError = error as? SpecialError {
    //ok myError is type SpecialError it has a foo method I can call
    if(myError.foo()) {
        //do something
    } else {
        //do something else
    }
} else { //myError not type SpecialError and is not nil
    // This is the case I'm interested in
    bar()
}

      

0


source


 if let theFoo = (error as? SpecialError)?.foo(){
       if theFoo != true{
           bar()
       } //in case you want to do handling if theFoo is true
   } //in case you want to do handling if error is not SpecialError

      

0


source







All Articles