[Pre-proposal] Allow multiple compatible enum cases in switch cases with named variables


(Haravikk) #1

There’s probably a more succinct title I could use, but this issue is best described by an example:

  enum Foo {
    case A(Int)
    case B(Int)
  }

In the above enum I have two cases, each containing an Int, so while they may have different meanings in their documentation, cases A and B could be said be compatible as they both store values of the same type.

However, the following isn’t currently possible:

  switch anInstanceOfFoo {
    case .A(let value), .B(let value):
      doSomethingInCommon(value)
  }

I recently had this come up recently in a situation where, although each case has a slightly different meaning, the stored values need to be in the same range and I wanted to validate them, however I’m currently forced to do this with two separate case statements (I opted to use fall through but it’s still not a great solution).

I’d like to propose that switch cases should allow multiple enum cases with named variables, provided the variables can be inferred to have the same type, and are all in common. I think for these purposes there should be a single named declaration, with others simply referring to the same variable. To expand upon the example a bit, let’s say I tweaked Foo.B to take a second value:

  enum Foo {
    case A(Int)
    case B(Int, Float)
  }

Although it’s now no longer directly comparable to A, I’d still like to be able to do the following:

  switch anInstanceOfFoo {
    case .A(let value), .B(value, _):
      doSomethingInCommon(value)
  }

In other words, this is fine because although B has a value not in common with A, it isn’t being used, i.e- only variables with a common type are being used and extracted to a constant named value, so everything’s okay.

Feedback welcome, also if anyone can think of something better to call this I’d love suggestions on that as well :wink:


#2

I believe it is possible as of 18 hours ago :slight_smile:

https://github.com/apple/swift/pull/1383

Stephen

···

On Feb 26, 2016, at 8:54 AM, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

However, the following isn’t currently possible:

  switch anInstanceOfFoo {
    case .A(let value), .B(let value):
      doSomethingInCommon(value)
  }