Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwrap an Enum Tuple outside of a Switch in Swift

Tags:

swift

So one of the cool new features in Swift is more advanced enums and the possibility to associate more complex data. For example, I could do something like this:

enum Location {
    case GeoPoint(latitude: Double, longitude: Double)
    case Address(address: String)
}

var address = Location.Address(address: "1234 Fake St, Fakesville TN, 41525")
var geoPoint = Location.GeoPoint(latitude: 42.342, longitude: -32.998)

// address or geoPoint
switch address {
case .Address(let addressStr):
    // Unwrapped value as 'addressStr'
    println("Address: \(addressStr)")
case .GeoPoint(let latitude, let longitude):
    // Unwrapped values as 'latitude' and 'longitude'
    println("lat: \(latitude) long: \(longitude)")
}

Is it possible to unwrap these inner values outside of a switch statement? Something like:

var addressStr = address.0

Why?

I don't have a good reason, I'm just experimenting with the language.

like image 932
Logan Avatar asked Jun 04 '14 00:06

Logan


3 Answers

Fortunately you can do that in Swift 2 with an if case:

if case .Address(let addressString) = address {
    // do something with addressString
}
like image 79
Qbyte Avatar answered Nov 20 '22 07:11

Qbyte


Edit: this is now possible in Swift 2+ https://stackoverflow.com/a/31272451/308315


I don't think it's possible, because an enum variable is not guaranteed to be a case with those inner values. You could add a computed property that unwraps it for you:

enum Location {

    var address: String? {
    get {
        switch self {
        case .Address(let address)
            return address
        default:
            return nil
        }
    }
    }

    case GeoPoint(latitude: Double, longitude: Double)
    case Address(address: String)
}

Then you can do:

var addressStr = address.address
like image 14
Austin Avatar answered Nov 20 '22 07:11

Austin


I think you are looking at enumeration wrong. The enumeration type can only be one of the values. In this case a location can only be a GeoPoint or an Address, not both. The switch statement determines which one it is. I think the functionality you are looking for here is a structure like this:

struct Geopoint{
    var longitude : Double = 0.0
    var latitude : Double = 0.0
}
struct Location{
    var address : String = ""
    var geopoint: Geopoint
}

Then you can create a new instance of Location and access its properties.

var location = Location(address: "1 Example Street ...", geopoint:Geopoint(longitude: 12.2, latitude: 53.2))

println(location.address);
like image 3
67cherries Avatar answered Nov 20 '22 08:11

67cherries