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]()
.