Types and meta type in Swift

Knowing the type and meta-type in Swift is not as common as in Smalltalk or Objective-C. Where in objective-c, you can instantiate an object out of a class name or modify classes at runtime this is not possible in Swift. This comes to the fact that Swift is a language that supports generics, and comes with strong typing and therefore does not provide many such features.

However, there are times when you need to know what type your instances or classes are. In that area, swift provides ways of getting the types and meta types.

class JaguarEType: Car {}
let myCar = JaguarEType()
JaguarEType.self == type(of:myCar) 🙃🙄

Type and meta Types

In Swift, there are two kinds of typesnamed types and compound types. A named type is a type that can be given a particular name when it’s defined. Named types include classes, structures, enumerations, and protocols. A compound type is a type without a name, defined in the Swift language itself. There are two compound types: function types and tuple types.

metatype type refers to the type of any type, including class types, structure types, enumeration types, and protocol types as well as compound types.

Type.self

The metatype of a class, structure, or enumeration type is the name of that type followed by .Type. The metatype of a protocol type—not the concrete type that conforms to the protocol at runtime—is the name of that protocol followed by  .Protocol. For example, the metatype of the class type SomeClass is SomeClass.Type and the metatype of the protocol SomeProtocol is SomeProtocol.Protocol.

The meta type of a type can be found by calling .self on a type. The returned type can either be a Class meta-type, a Struct meta-type, a Protocol meta-type or function type.

class C {}
struct S {}
protocol P {}
enum E: Int {
   case a
   case b
}
func F() {}

print(C.Type.self)    // C.Type
print(S.Type.self)    // S.Type
print(P.Type.self)    // P.Type.Protocol
print(E.Type.self)    // E.Type

type(of:_)

If .self is used on a type to return its meta type, type(of:)is used on a instance to return the instance type.

print(type(of:S()))   // S
print(type(of:C()))   // C
print(type(of:E.a))   // E
print(type(of:F))     // () -> ()

S.self == type(of:S()) // true
C.self == type(of:C()) // true
E.self == type(of:E.a) // true

Self

The Self type isn’t a specific type, but rather lets you conveniently refer to the current type without repeating or knowing that type’s name.

In a protocol declaration or protocol member declaration, the Self type refers to the eventual type that conforms to the protocol.

In a structure, class, or enumeration declaration, the Selftype refers to the type introduced by the declaration. Inside the declaration for a member of a type, the Selftype refers to that type.

tomkausch

Leave a Reply

Your email address will not be published. Required fields are marked *