From here I will explain protocol qualifiers.
Consider the following two protocols:
protocol P1 {
associatedtype Item
var description: String { get }
}
protocol P2 {
associatedtype Item
var description: String { get }
}
P1 and P2 have an associated type with the same name Item
and a property with the same name description
.
Data types conforming to these two protocols are defined as follows.
struct S: P1, P2 {
typealias Item = Int
var description: String = "foo"
}
Item
in P1 and Item
in P2 will have the same data type.
description
of P1 and description
of P2 will have the same entity.
The same is true for methods instead of properties.
I think this is the current Swift spec, is this the way it should be?
I think it's always possible to have a situation where you want to give each protocol a different data type or property entity, but you can't because they have the same name.
As it stands, I think they try to use names that are unlikely to match others to avoid this problem.
The example I just gave is a problem between protocols trying to conform to it at the same time, but it also happens when you inherit from one protocol and define another.
In this case too, we have to avoid unintended name matching, so for example, give a slightly longer name as shown below.
protocol P1 {
associatedtype P1Item
var p1Description: String { get }
}
protocol P2: P1 {
associatedtype P2Item
var p2Description: String { get }
}
Although story changes,
Many delegation protocols unify all method names with the protocol name.
I think the purpose of doing so is to avoid name clashes with other protocols and to make it easier to identify which protocol it belongs to from the method name.
The various delegation protocol methods of UITableView, which I often use, have a well-thought-out interface, and I think it's amazing, but I think it's hard for me to define an interface like this myself.
Despite the lengthy preamble, these considerations gave me a good idea.
One is the idea of associated types, already mentioned here.
This completely prevents associated type name collisions.
I will proceed on the premise that I have adopted this idea.
Another is protocol modifiers.
It is used in front of protocol properties and methods.
To give a simple example,
protocol P1<Item> {
var description: String { get }
}
protocol P2<Item> {
var description: String { get }
}
struct S: P1<Item: Int>, P2<Item: String> {
var P1::description: String = "foo" // Attention here!
var P2::description: String = "foo" // Attention here!
}
Properties and methods defined in a protocol should be used in pairs with the protocol name.
The delimiter "::" is the same symbol as the scope resolution operator in C++, but in Swift it is only used to give the protocol name.
By doing this, the protocol-related properties and methods are always written in pairs with the protocol name, so I think it will improve the readability of the program.
Property names and method interfaces can also be more concise.
If the protocol name makes the description rather long, you can also use a short name typealias that refers to the protocol.
The overview of protocol modifiers ends here.
Next, I'd like to explain my ideas for changing protocol definitions and default implementations of requirement elements.