Reputation: 7079
Swift's Array type implements Equatable protocol in a way that == and != operators are overloaded:
extension Array : Equatable where Element : Equatable {
/// - Parameters:
/// - lhs: An array to compare.
/// - rhs: Another array to compare.
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
public static func != (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}
I've got three questions:
[[Element].Element]
? So far my reasoning is:
[Element]
is a type definition, i.e. an array of types denoted by
Element
(Element
is a placeholder type name). [Element].Element
means as .Element
is puzzling for me.Upvotes: 4
Views: 203
Reputation: 539805
Generally, TypeA.TypeB
can denote a nested type or type alias TypeB
inside TypeA
, or an associated type TypeB
of a protocol TypeA
.
Array
conforms to Sequence
, and that has an associatedtype Element
for the type of the elements returned from its iterator. For arrays
that is equal to the array's element type. So for any type T
:
Array<T>.Element == T
and consequently,
[Array<T>.Element] == [T]
Example:
print(type(of: [Array<Int>.Element].self))
// Array<Int>.Type
However, using the bracket notation for the inner array is not accepted by the compiler:
print(type(of: [[Int].Element].self))
// Expected member name or constructor call after type name
Now back to your question: The actual definition of that ==
operator is
extension Array : Equatable where Element : Equatable {
public static func ==(lhs: Array<Element>, rhs: Array<Element>) -> Bool {
// ...
}
}
The “generated interface” is, as you noticed:
extension Array : Equatable where Element : Equatable {
public static func == (lhs: [[Element].Element], rhs: [[Element].Element]) -> Bool
}
So apparently, the “interface generator” interprets the Element
in lhs: Array<Element>
not as the placeholder type, but as the associated
Element
type of the Sequence
protocol, i.e. the types of the operands
are
Array<Array<Element>.Element>
which – as shown above – is just [Element]
. But then the interface
is emitted using the bracket notation
[[Element].Element]
which should be the same, but is not accepted by the compiler.
Upvotes: 2