Swift 5 allows protocols to "constrain their conforming types to those that subclass a given class". This is implemented as (taken directly from the release notes)-
protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ }
Given that the :
character is generally used to indicate either inheritance or conformance in protocol
/class
/struct
definitions, reading the above in my opinion is jarring for both a beginner and an experienced Swift user. I was curious behind the rationale of this decision (I couldn't find the relevant evolution proposal), given that one of the primary tenets of Swift is expressive code. This is in direct conflict when you can have valid definitions such as-
protocol Mock: SIMD, NSFetchRequest<NSNumber> where MaskStorage == SIMD4<Int> { }
Background
I was recently writing a series of posts related to RealityKit
when I noticed the following interface description for HasHierarchy
-
protocol HasHierarchy: Entity {
/// ...
}
Based on my experience with RealityKit
, I knew that Entity
was a class
, which instinctively made me infer the above as "protocol HasHierarchy
inherits from Entity
", which is semantically incorrect in Swift. If I had no prior knowledge of Entity
, I would instead deduce that Entity
is a protocol and HasHierarchy
inherits from it (given this is the "general" pattern).
Discussion
I understand that the :
character is contextual, and has different meanings based on where it is used (function/property definitions, ternary operator, etc). However, when the context is defined, it usually has servers a singular purpose (correct me if I'm wrong). For instance, let myProperty: Int
has an unambiguous meaning.
However, this is not the case for class
/enum
/struct
/protocol
definition, as the reader needs to have prior knowledge of the objects succeeding :
. From the example at the top, the reader needs to be aware that SIMD
is a protocol and NSFetchRequest
is a class to disambiguate the definition (I acknowledge this was a contrived example, but the point still stands).