What does [[Element].Element] mean in Swift's == operator overload?
up vote
4
down vote
favorite
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:
- What is
[[Element].Element]
? - How to read that?
- Why I cannot use that construct in my Swift code?
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).- Based on 1, next I reckon outermost brackets denote another array, BUT...
- I can't figure out what
[Element].Element
means as.Element
is puzzling for me.
swift
add a comment |
up vote
4
down vote
favorite
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:
- What is
[[Element].Element]
? - How to read that?
- Why I cannot use that construct in my Swift code?
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).- Based on 1, next I reckon outermost brackets denote another array, BUT...
- I can't figure out what
[Element].Element
means as.Element
is puzzling for me.
swift
2
That code doesn't even compile, where did you get that from? That's not from the official Swift source code ofArray
.
– Dávid Pásztor
Nov 8 at 11:53
@DávidPásztor: Actually, if you select the “==” inif array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
– Martin R
Nov 8 at 12:12
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
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:
- What is
[[Element].Element]
? - How to read that?
- Why I cannot use that construct in my Swift code?
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).- Based on 1, next I reckon outermost brackets denote another array, BUT...
- I can't figure out what
[Element].Element
means as.Element
is puzzling for me.
swift
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:
- What is
[[Element].Element]
? - How to read that?
- Why I cannot use that construct in my Swift code?
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).- Based on 1, next I reckon outermost brackets denote another array, BUT...
- I can't figure out what
[Element].Element
means as.Element
is puzzling for me.
swift
swift
edited Nov 8 at 12:30
asked Nov 8 at 11:40
matm
6,11942949
6,11942949
2
That code doesn't even compile, where did you get that from? That's not from the official Swift source code ofArray
.
– Dávid Pásztor
Nov 8 at 11:53
@DávidPásztor: Actually, if you select the “==” inif array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
– Martin R
Nov 8 at 12:12
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24
add a comment |
2
That code doesn't even compile, where did you get that from? That's not from the official Swift source code ofArray
.
– Dávid Pásztor
Nov 8 at 11:53
@DávidPásztor: Actually, if you select the “==” inif array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.
– Martin R
Nov 8 at 12:12
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24
2
2
That code doesn't even compile, where did you get that from? That's not from the official Swift source code of
Array
.– Dávid Pásztor
Nov 8 at 11:53
That code doesn't even compile, where did you get that from? That's not from the official Swift source code of
Array
.– Dávid Pásztor
Nov 8 at 11:53
@DávidPásztor: Actually, if you select the “==” in
if array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.– Martin R
Nov 8 at 12:12
@DávidPásztor: Actually, if you select the “==” in
if array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.– Martin R
Nov 8 at 12:12
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
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.
thank you for a very insightful answer. Following simple logic, sinceArray<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent toArray<Element>
. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
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.
thank you for a very insightful answer. Following simple logic, sinceArray<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent toArray<Element>
. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12
add a comment |
up vote
2
down vote
accepted
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.
thank you for a very insightful answer. Following simple logic, sinceArray<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent toArray<Element>
. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
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.
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.
edited Nov 8 at 19:28
answered Nov 8 at 12:18
Martin R
387k54838947
387k54838947
thank you for a very insightful answer. Following simple logic, sinceArray<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent toArray<Element>
. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12
add a comment |
thank you for a very insightful answer. Following simple logic, sinceArray<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent toArray<Element>
. I've accepted the answer. Many thanks for your detailed answer.
– matm
Nov 9 at 9:12
thank you for a very insightful answer. Following simple logic, since
Array<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>
. I've accepted the answer. Many thanks for your detailed answer.– matm
Nov 9 at 9:12
thank you for a very insightful answer. Following simple logic, since
Array<T>.Element == T
is a tautology, so when array literal is applied, the end result is equivalent to Array<Element>
. I've accepted the answer. Many thanks for your detailed answer.– matm
Nov 9 at 9:12
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53207017%2fwhat-does-element-element-mean-in-swifts-operator-overload%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
That code doesn't even compile, where did you get that from? That's not from the official Swift source code of
Array
.– Dávid Pásztor
Nov 8 at 11:53
@DávidPásztor: Actually, if you select the “==” in
if array1 == array2
and choose "Navigate -> Jump to Definition” in Xcode (10.1) then you'll see exactly the above definition. – Probably an artefact of the generated interface.– Martin R
Nov 8 at 12:12
@DávidPásztor Jump to definition on Array type in Xcode and then look up Equatable. That's a real bummer that Xcode could not show the interface generated properly from the code you've linked to.
– matm
Nov 8 at 12:24