/// The protocol to which all types implicitly conform.
public typealias Any = protocol<>
Any
is just a protocol that all types implicitly conform to – it's not a concrete type itself. Swift cannot infer an array of non-concrete types, which is why it fails to infer Any
, but succeeds with NSObject
(Int
can be bridged to NSNumber
, String
can be bridged to NSString
– and they both inherit from NSObject
, which is a concrete type).
For example, consider this:
protocol Foo {}
struct Bar:Foo {}
struct Baz:Foo {}
let arr = [Bar(), Baz()] // error: Type of expression is ambiguous without more context
Because Foo
is a non-concrete type, Swift cannot infer an array of it. You have to explicitly tell the compiler what you want its type to be:
let arr:[Foo] = [Bar(), Baz()]
You'll also get the same behaviour with AnyObject
(as it's a protocol that all classes implicitly conform to – but still not a concrete type):
class Qux {}
class Fox {}
let a = [Qux(), Fox()] // error: Type of expression is ambiguous without more context
let a1:[AnyObject] = [Qux(), Fox()] // no error
Why Swift is unable to infer an array of non-concrete types is most likely due to the existing limitations of non-concrete types in the language – currently concrete types are required for most non-trivial operations. See this great Q&A for an example.
But to be honest, you should really be thinking more about whether you actually need an array of Any
. I cannot think of a single practical application of having an array of Any
, as because everything implicitly conforms to the elements, they must be guaranteed to do nothing (you can't call a specific method on something that could be anything). Sure you can type-cast, but what's the point in getting back the type safety that you threw away to begin with?
You should always be as type specific as you can. You could build a wrapper for your values – this could either be a simple struct
to wrap a couple of properties, or a type erasure in order to wrap non-concrete types in a pseudo concrete type. At the very least, you should consider creating your own protocol that your array elements conform to.
NSObject
(orAnyObject
which wouldn't work here but I see it used all the time) isn't that much more specific thanAny
. – Airlee