6

I'm trying to create a dictionary variable whose values are one of two types. An example of my attempt should make this clearer:

var objects: <T where T: Float, T: Bool>[String: T]

This throws a compiler error that only syntactic function types can be generic. I wonder if it is possible, I just don't know the correct syntax?

Nick
  • 3,958
  • 4
  • 32
  • 47

1 Answers1

20

The tool you want for this is an enum with associated data.

enum Stuff {
  case FloatyThing(Float)
  case BoolyThing(Bool)
}

let objects = ["yes!"   : Stuff.BoolyThing(true),
               "number" : Stuff.FloatyThing(1.0)]

This captures "an object that is either a float or a bool" and provides better documentation and type safety.

To unload the data, you use a switch statement:

if let something = objects["yes!"] {
  switch something {
    case .FloatyThing(let f): println("I'm a float!", f)
    case .BoolyThing(let b): println("Am I true?", b)
  }
}

The use of the switch statement makes sure you cover all the possible types and prevents you from accidentally unloading the data as the wrong type. Pretty nice that the compiler can help you so much.

For more, see "Enumerations and Structures" in the Swift Programming Language.

I also recommend Error Handling in Swift by Alexandros Salazar for a very nice example of how this can be used to deal with common problems.

Nate Cook
  • 92,417
  • 32
  • 217
  • 178
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • How do you determine what type the value is, or switch on the value? – Nick Jul 14 '14 at 13:56
  • 2
    Updated with some more background. This is a very powerful feature in Swift and I expect it to be very common. – Rob Napier Jul 14 '14 at 14:20
  • Can you write an if statement to check the type? E.g. `if something is .FloatyThing(let f)` – Nick Jul 14 '14 at 15:19
  • I don't know of an 'if' syntax for that, but the switch syntax isn't complex: `switch f { case .FloatyThing(let x): print(x); default: break }`. That said, this sounds like a case where you'd want to rethink your algorithm. Ignoring the other cases is an easy source of bugs. It's better to even say "I know this case exists and I'm intentionally doing nothing" than to just skip over things you didn't expect. – Rob Napier Jul 14 '14 at 16:02