What is the fundamental difference between SomeProtocol.Protocol and SomeProtocol.Type?

56 Views Asked by At

By chance, I observed some differences in behaviour between the types SomeProtocol.Protocol and SomeProtocol.Type (before this, I thought they are the same thing!):

public protocol P {
}

public class C: P {
}

protocol Q: P {}

P.self is P.Protocol // true
P.self is P.Type     // false
Q.self is P.Protocol // false
Q.self is P.Type     // false
C.self is P.Protocol // false
C.self is P.Type     // true

// this seems to be consistent with function invocation expressions, which is expected
func a(_ x: P.Protocol) { }
func b(_ x: P.Type) { }
a(P.self)
b(P.self) // error
a(Q.self) // error
b(Q.self) // error
a(C.self) // error
b(C.self)

What surprised me is P.self is P.Protocol, because I know protocols don't conform to themselves, so I expected it to be true...

Anyway, I cannot see what the fundamental difference between .Protocol and .Type that caused this difference in behaviour. I expect that the two syntaxes probably mean something subtly different...

I checked the Swift guide on meta types, which just says:

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.

It doesn't seem to acknowledge the existence of SomeProtocol.Type!

What is the difference between .Protocol and .Type?

(In case it's unclear, I'm looking for an answer along the lines of ".Protocol means this, where .Type means that")

0

There are 0 best solutions below