Storing different types of value in Array in Swift

AnyObject is a type and you can create an array that holds those, which (as the class name implies) means it can hold any type of object. NSArrays aren't type-bound and when you create an array with mixed types, it will generate an NSArray instead of an Array. I wouldn't rely on this, however, since it could change in the future (AnyObject[] is automatically bridged with NSArray).

You can try this in a playground (note: dynamicType returns "(Metatype)" and I wasn't sure how to pull out the actually type so I relied on the compiler error):

var x = [ 1, 2, "a" ]
x.dynamicType.description() // -> __NSArrayI

var y = [ 1, 2 ]
y.dynamicType.description() // -> Error: Array<Int>.Type does not have a member named 'description'.

var z: AnyObject[] = [ 1, 2, "a" ]
z.dynamicType.description() // -> Error: Array<AnyObject>.Type does not have a member named 'description'.

In Swift 3 you can use :

var testArray = ["a",true,3,"b"] as [Any]

From REPL

 xcrun swift
  1> import Foundation
  2> var test = ["a", "b", true, "hi", 1]
test: __NSArrayI = @"5 objects" {
  [0] = "a"
  [1] = "b"
  [2] =
  [3] = "hi"
  [4] = (long)1
}
  3>

you can see test is NSArray, which is kind of AnyObject[] or NSObject[]

What happening is that Foundation provides the ability to convert number and boolean into NSNumber. Compiler will perform the conversion whenever required to make code compile.

So they now have common type of NSObject and therefore inferred as NSArray


Your code doesn't compile in REPL without import Foundation.

 var test = ["a", "b", true, "hi", 1]
<REPL>:1:12: error: cannot convert the expression's type 'Array' to type 'ArrayLiteralConvertible'

 var test:Array = ["a", "b", true, "hi", 1]
<REPL>:4:18: error: cannot convert the expression's type 'Array' to type 'ExtendedGraphemeClusterLiteralConvertible'

but you can do this

var test : Any[] = ["a", "b", true, "hi", 1]

Because they have a common type, which is Any.


Note: AnyObject[] won't work without import Foundation.

var test:AnyObject[] = ["a", "b", true, "hi", 1]
<REPL>:2:24: error: type 'Bool' does not conform to protocol 'AnyObject'

To initialize an Array with arbitrary types, just use var arbitraryArray = [Any]().

Tags:

Swift