In Swift we are able to write following construction:
class SomeClass {} let metaMetatype: SomeClass.Type.Type = SomeClass.Type.self
Here metaMetatype
does not conform to type AnyObject
(SomeClass.Type
does). Construction can be even longer, as long as we wish:
let uberMetatype: SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.Type = SomeClass.Type.Type.Type.Type.Type.Type.Type.Type.Type.self
Are this constructions have any sense? If SomeClass.Type.Type
not an object, what is this, and why we able to declare it?
Definition of metatype : a topotype or homeotype determined by the original author of its species.
A metatype referes to the type of any type, including class types, structure types, enumeration types, and protocol types. /.../ You can use the postfix self expression to access a type as a value. For example, SomeClass. self returns SomeClass itself, not an instance of SomeClass.
If
SomeClass.Type.Type
not an object, what is this and why we able to declare it?
I will try to dissect what you're asking.
SomeClass.Type.Type
is a Metatype of a Metatype. Metatypes exist in Swift because Swift has types that are not classes. This is most similar to the Metaclass concept in Objective-C.
Lexicon.rst in the Swift Open Source Repo has a pretty good explanation:
metatype
The type of a value representing a type. Greg Parker has a good explanation of Objective-C's "metaclasses" because Swift has types that are not classes, a more general term is used.
We also sometimes refer to a value representing a type as a "metatype object" or just "metatype", usually within low-level contexts like IRGen and LLDB. This is technically incorrect (it's just a "type object"), but the malapropism happened early in the project and has stuck around.
Why are we able to declare a type of a type of a type... and so on? Because it's a feature of the language called type metadata:
type metadata
The runtime representation of a type, and everything you can do with it. Like a
Class
in Objective-C, but for any type.
Note that you can't do something like NSObject().class
in Swift because class
is a reserved keyword for the creation of a class. This is how you would get the type (or class in this case) of an NSObject in Swift:
let nsObj = NSObject() nsObj.classForCoder // NSObject.Type nsObj.classForKeyedArchiver // NSObject.Type nsObj.dynamicType // NSObject.Type
Note that nsObj
and nsObj.self
are identical and represent the instance of that NSObject
.
I don't see where in the Swift module or open source repo where types allow for .Type
, but I'm still looking. It might have to do with the inheritance from SwiftObject, the Objective-C object all Swift classes inherit from (at least on Mac).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With