There are two collection types in Swift standard library: Array and Dictionary:

struct Array<T> :
    MutableCollectionType, Sliceable {



struct Dictionary<Key : Hashable, Value> :
    CollectionType, DictionaryLiteralConvertible {



They are all generic. That means we can only put elements of the same type into a collection, such as:

let numbers = [1,2,3,4,5]
// numbers is [Int]

let strings = ["hello", "world"]
// strings is [String]

There is also a way to put things of different concrete types together, by using Any or AnyObject, or just by turning to the classical NSArray:

import UIKit

let mixed: [Any] = [1, "two", 3]

// If no specified type, since the existing of UIKit
// objectArray would be inferred as [NSObject]
let objectArray = [1, "two", 3]

Some type information will get lost in this conversion. When we try to retrieve an element from the collection, we have no way to know what original type it is, except to do a type cast. It might be the last choice for us to put elements with different types together, at risk in type safety. The compiler will not help anymore and we can add or convert the elements easily. That's too bad.

let any = mixed[0]  
// It is an `Any`, but should be an Int in fact.
// The type information is lost.

let nsObject = objectArray[0]
// It is an `NSObject` now.

We notice that Any is a protocol instead of a concrete type. It says, besides of putting elements of the same type into a collection, we can also put things conforming to a same protocol into it. In most situations, since we will put the elements more or less similar into one collection, using protocol as the type of the collection would be a good idea. In the example above, consider the case we want to use description to print some information about these elements, instead of declaring an [Any] array, we prefer using [Printable]:

import Foundation
let mixed: [Printable] = [1, "two", 3]

for obj in mixed {

While some type information is lost, it is much better than either Any or AnyObject. Another possible approach would be relying on the fact that enum could take a value in Swift. We can seal some type information into an enum package and retrieve them later. Here is an example which takes advantage of putting Int or String into an enum type:

import Foundation
enum IntOrString {
    case IntValue(Int)
    case StringValue(String)

let mixed = [IntOrString.IntValue(1),

for value in mixed {
    switch value {
    case let .IntValue(i):
        print(i * 2)
    case let .StringValue(s):

// Output:
// 2
// Two
// 6

By doing this, we keep all the information of different types in compile time. We could even create a literal conversion for IntOrString to make things easier, but it is another story.