for case enum syntax

In the "What's New in Swift" video, the following pattern is shown on a slide:


for case .MyEnumCase (let value) in enumValues


But tests in Xcode 7 show that this sort of thing won't compile (with suitable declaration of a MyEnum that has a .MyEnumCase with associated value, and setting enumValues to a [MyEnum] value. The simpler syntax:


for case .MyEnumCase in enumValues


does compile, but of course doesn't give access to the associated value. Anyone know if this is merely a compiler defect, or if the actual syntax is something different?

Answered by Jens in 9383022

Apparently the "let" have to be outside the parens, following "case", like this:

enum SomeEnum {
    case Uppercase(String)
    case Lowercase(String)
    case Suitcases(Int)
}

let enumValues: [SomeEnum] = [.Uppercase("A"), .Lowercase("b"), .Suitcases(100), .Uppercase("FOO")]

for case let .Uppercase(value) in enumValues {
    print(value)
}

// Prints
// A
// FOO

I can't see anything mentioned about this particular kind of "for case" (extracting associated values) in the iBook either.

Accepted Answer

Apparently the "let" have to be outside the parens, following "case", like this:

enum SomeEnum {
    case Uppercase(String)
    case Lowercase(String)
    case Suitcases(Int)
}

let enumValues: [SomeEnum] = [.Uppercase("A"), .Lowercase("b"), .Suitcases(100), .Uppercase("FOO")]

for case let .Uppercase(value) in enumValues {
    print(value)
}

// Prints
// A
// FOO

I can't see anything mentioned about this particular kind of "for case" (extracting associated values) in the iBook either.

Yes, but it doesn't really tell anything explicitly about this particular use case (iterating over a collection of enums with associated values, and only over the ones that matches a particular member value, getting a copy of the associated value from each of them).


The closest thing on that page (and in the iBook) is this example:

let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
// Match only non-nil values
for case let number? in arrayOfOptionalInts {
    print("Found a \(number)")
}
// Found a 2
// Found a 3
// Found a 5


Yes, number? is short for .Some(number), but using the special ?-form also hides the more general form of the pattern. The example is focusing on the special case of Optionals which is fine, but it also obscures the general pattern. And I don't think most people will quckly deduce this from that example or by analyzing the grammar.


Perhaps there should be some additional example using the pattern in question, ie:

for case let .Foo(value) in enumValues { ...


Especially if the syntax in the WWDC 2015 video was showing invalid syntax while they were talking about this (haven't checked that myself).

AFAICT, in a switch statement, 'case let .Foo (value)' and 'case .Foo (let value) are the same thing.


In a for…in, statement, I'm not sure what's supposed to be happening. Clearly the 'let' isn't allowed to migrate inside the parentheses right now, but maybe that's coming in the future.


But the other issue is whether there's going to be a binding for the enum value itself (aside from the associated value). A switch statement can have multiple values in a case, so is there a valid situation like this:


for case .Foo, .Bar in someArray {…}


Obviously if there is, there needs to be a let binding in there somewhere that would bind to the enum value itself. I'm not saying I think this should be possible. I'm just wondering what the limits are, since they don't seem to be well-described yet.

for case enum syntax
 
 
Q