A single expression for guard case let with type casting of the associated type?

Viewed 7191

I have the following enum:

enum JSONData {
    case dict([String:Any])
    case array([Any])
}

I would like to do a pattern matching assignment with type casting using guard case let. I not only want to make sure that someData is .array, but that its associated type is [Int] and not just [Any]. Is this possible with a single expression? Something like the following:

let someData: JSONData = someJSONData()
guard case let .array(anArray as [Int]) = someData
else { return }

But the above does not compile; the error is downcast pattern value of type '[Int]' cannot be used. I know this is possible with the following but I'd rather do it in a single expression if possible.

guard case let .array(_anArray) = someData, let anArray = _anArray as? [Int]
else { return }

Edit on April 27, 2018: An update to this situation: you may now use the following syntax as long as the cast type is not a Collection:

enum JSONData {
    case dict([String:Any])
    case array(Any)  // Any, not [Any]
}

func f() {
    let intArray: JSONData = .array(1)
    guard case .array(let a as Int) = intArray else {
        return
    }
    print("a is \(a)")
}

f()  // "a is 1"

If you attempt to use a collection type such as [Int], you receive the error error: collection downcast in cast pattern is not implemented; use an explicit downcast to '[Int]' instead.

1 Answers
Related