I could not figure out the purpose/meaning of "Indices.Iterator.Element == Index" in following code
我无法在下面的代码中找出“Indices.Iterator.Element == Index”的目的/含义
extension Collection where Indices.Iterator.Element == Index {
/// Returns the element at the specified index iff it is within bounds, otherwise nil.
subscript (safe index: Index) -> Generator.Element? {
return indices.contains(index) ? self[index] : nil
}
}
2 个解决方案
#1
7
The generic constraint syntax where T == U
says that the type T
must be the same type as type U
.
通用约束语法,其中T == U表示类型T必须与类型U的类型相同。
Let's do a simpler example first:
让我们先做一个更简单的例子:
protocol GenericProtocol {
associatedtype T
associatedtype U
}
extension GenericProtocol where T == U {
func foo() {}
}
class ConcreteClassA: GenericProtocol {
typealias T = Int
typealias U = Float
}
class ConcreteClassB: GenericProtocol {
typealias T = Int
typealias U = Int
}
let a = ConcreteClassA()
let b = ConcreteClassB()
Now which of these, a
or b
has the member foo
? The answer is b
.
现在哪一个,a或b有成员foo?答案是b。
Since the extension's generic constraint says that T
and U
must be the same type, the extension is only applied to ConcreteClassB
because its T
and U
are both Int
.
由于扩展的泛型约束表明T和U必须是相同的类型,因此扩展仅应用于ConcreteClassB,因为它的T和U都是Int。
Back to your code now.
现在回到你的代码。
In your code, you're saying that Indices.Iterator.Element
must be the same type as Index
. Let's figure what these two types are respectively.
在您的代码中,您说Indices.Iterator.Element必须与Index类型相同。让我们分别说明这两种类型。
Indices
is the type of the property indices
. So Indices.Iterator.Element
is type of each index of the collection. Index
on the other hand, is the type of value that you can put into the subscript of of the collection. This constraint seems excessive but it is in fact not. I can't think of an example of a type where the constraint is not true. But you can in theory create such a type. That's why the constraint is there.
指数是房地产指数的类型。所以Indices.Iterator.Element是集合的每个索引的类型。另一方面,索引是可以放入集合下标的值的类型。这种约束似乎过多,但实际上并非如此。我想不出约束不正确的类型的例子。但是你可以从理论上创造出这样一种类型。这就是约束存在的原因。
If the constraint weren't there, this would not compile:
如果没有约束,则无法编译:
indices.contains(index)
#2
2
contains(_:)
is being called on the indices
property (which has type Indices
), with the parameter called index
(which has type Index
). The only way this is possible is if the Indices
elements are of the same type as Index
.
contains(_ :)是在indices属性(具有类型Indices)上调用的,其参数名为index(具有类型Index)。唯一可行的方法是Indices元素与Index的类型相同。
This constraint is added to assert that this is true, thus allowing the code to compile.
添加此约束以断言这是真的,从而允许代码进行编译。
Take Array
of example. Its Indices
associated type is set to CountableRange<Int>
and its Index
associated type is set to Int
. Array is able to conform to your protocol because it's true that the elements of the iterator of CountableRange<Int>
(CountableRange<Int>.Iterator.Element
) and the type of Index
are both Int
.
以数组为例。其Indices关联类型设置为CountableRange
#1
7
The generic constraint syntax where T == U
says that the type T
must be the same type as type U
.
通用约束语法,其中T == U表示类型T必须与类型U的类型相同。
Let's do a simpler example first:
让我们先做一个更简单的例子:
protocol GenericProtocol {
associatedtype T
associatedtype U
}
extension GenericProtocol where T == U {
func foo() {}
}
class ConcreteClassA: GenericProtocol {
typealias T = Int
typealias U = Float
}
class ConcreteClassB: GenericProtocol {
typealias T = Int
typealias U = Int
}
let a = ConcreteClassA()
let b = ConcreteClassB()
Now which of these, a
or b
has the member foo
? The answer is b
.
现在哪一个,a或b有成员foo?答案是b。
Since the extension's generic constraint says that T
and U
must be the same type, the extension is only applied to ConcreteClassB
because its T
and U
are both Int
.
由于扩展的泛型约束表明T和U必须是相同的类型,因此扩展仅应用于ConcreteClassB,因为它的T和U都是Int。
Back to your code now.
现在回到你的代码。
In your code, you're saying that Indices.Iterator.Element
must be the same type as Index
. Let's figure what these two types are respectively.
在您的代码中,您说Indices.Iterator.Element必须与Index类型相同。让我们分别说明这两种类型。
Indices
is the type of the property indices
. So Indices.Iterator.Element
is type of each index of the collection. Index
on the other hand, is the type of value that you can put into the subscript of of the collection. This constraint seems excessive but it is in fact not. I can't think of an example of a type where the constraint is not true. But you can in theory create such a type. That's why the constraint is there.
指数是房地产指数的类型。所以Indices.Iterator.Element是集合的每个索引的类型。另一方面,索引是可以放入集合下标的值的类型。这种约束似乎过多,但实际上并非如此。我想不出约束不正确的类型的例子。但是你可以从理论上创造出这样一种类型。这就是约束存在的原因。
If the constraint weren't there, this would not compile:
如果没有约束,则无法编译:
indices.contains(index)
#2
2
contains(_:)
is being called on the indices
property (which has type Indices
), with the parameter called index
(which has type Index
). The only way this is possible is if the Indices
elements are of the same type as Index
.
contains(_ :)是在indices属性(具有类型Indices)上调用的,其参数名为index(具有类型Index)。唯一可行的方法是Indices元素与Index的类型相同。
This constraint is added to assert that this is true, thus allowing the code to compile.
添加此约束以断言这是真的,从而允许代码进行编译。
Take Array
of example. Its Indices
associated type is set to CountableRange<Int>
and its Index
associated type is set to Int
. Array is able to conform to your protocol because it's true that the elements of the iterator of CountableRange<Int>
(CountableRange<Int>.Iterator.Element
) and the type of Index
are both Int
.
以数组为例。其Indices关联类型设置为CountableRange