3

I have the following code:

class Base {}
class A: Base {}
class B: Base {}
class C: Base {}

func next(obj: Base) -> Base {
    if obj is A { return B() }
    else if obj is B { return C() }
    else if obj is C { return A() }
    else { return A() }
}

How do I express the chained ifs as a single switch statement instead?

3 Answers3

6
extension Base {

    func next() -> Base {
        switch self {
        case is A: return B()
        case is B: return C()
        case is C: return A()
        default: return A()
        }
    }

}
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • As a side note, if you have `class X: B` and you call `next` on an instance of it, it will return `C`, and not the `A` from the `default` case. – Iulian Onofrei Dec 14 '20 at 14:03
3

Surprisingly, it's exactly what you would think but wouldn't expect to work:

switch obj {
case (is A):
    // do something
case (is B):
    // do something
case (is C):
    // do something
default:
    // do something
}

Note that the parenthesis aren't necessary, I just like them for readability.

Jon Shier
  • 12,200
  • 3
  • 35
  • 37
2

Ideally you avoid using if statements in this scenario by making use of polymophism.

For example, in the base class you define a method X() and override it in each subclass to return B(), C(), A(), etc.

Then in your next method, just return obj.X().

There's a lot more on this topic here. Obligatory appeal to authority (Martin Fowler) here.

Community
  • 1
  • 1
Julian
  • 2,837
  • 17
  • 15
  • 1
    No, this would not do. I would like to separate each object with its knowledge of the others –  Nov 28 '15 at 02:30
  • This works if he can change the original class definitions. If he cannot change them, this doesn't work. You can't do it with extensions because, as of Swift 2.1, the compiler says “error: declarations in extensions cannot override yet”. – rob mayoff Nov 28 '15 at 02:31
  • I see that you and others have answered the question as asked which is perfectly reasonable, however when I've seen this conditional approach used in production code it was usually not the right one and could be refactored as I describe. – Julian Nov 28 '15 at 02:34