Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - what's the difference between metatype .Type and .self?

Tags:

swift

What's the difference between metatype .Type and .self in Swift?

Do .self and .Type return a struct?

I understand that .self can be used to check with dynamicType. How do you use .Type?

like image 790
Boon Avatar asked Jul 15 '15 18:07

Boon


People also ask

What is the difference between self and self in Swift?

“Self” as a Type in Swift This “Self” has an uppercase “S”, which is how you can tell it apart from the lowercase self. In Swift, Self refers to a type – usually the current type in the current context. Just as lowercase self can mean any current object, uppercase Self can mean just about any current type.

What does .type mean in Swift?

In Swift, there are two kinds of types: named 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.

What does type and self mean in Swift?

Type is the type and String. self is the value of a metatype. let intMetatype: Int. Type = Int.

What does self mean in Swift?

In Swift self is a special property of an instance that holds the instance itself. Most of the times self appears in an initializer or method of a class, structure or enumeration. The motto favor clarity over brevity is a valuable strategy to follow.


1 Answers

Here is a quick example:

func printType<T>(of type: T.Type) {     // or you could do "\(T.self)" directly and     // replace `type` parameter with an underscore     print("\(type)")  }   printType(of: Int.self) // this should print Swift.Int   func printInstanceDescription<T>(of instance: T) {     print("\(instance)") }   printInstanceDescription(of: 42) // this should print 42 

Let's say that each entity is represented by two things:

  • Type: # entitiy name #

  • Metatype: # entity name # .Type

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

Source.

You can quickly notice that this is recursive and there can by types like (((T.Type).Type).Type) and so on.

.Type returns an instance of a metatype.

There are two ways we can get an instance of a metatype:

  • Call .self on a concrete type like Int.self which will create a static metatype instance Int.Type.

  • Get the dynamic metatype instance from any instance through type(of: someInstance).

Dangerous area:

struct S {} protocol P {}  print("\(type(of: S.self))")      // S.Type print("\(type(of: S.Type.self))") // S.Type.Type print("\(type(of: P.self))")      // P.Protocol print("\(type(of: P.Type.self))") // P.Type.Protocol 

.Protocol is yet another metatype which only exisits in context of protocols. That said, there is no way how we can express that we want only P.Type. This prevents all generic algorithms to work with protocol metatypes and can lead to runtime crashes.

For more curious people:

The type(of:) function is actually handled by the compiler because of the inconsistency .Protocol creates.

// This implementation is never used, since calls to `Swift.type(of:)` are // resolved as a special case by the type checker. public func type<T, Metatype>(of value: T) -> Metatype { ... } 
like image 62
DevAndArtist Avatar answered Sep 29 '22 16:09

DevAndArtist