什么是“Collection where Indices.Iterator.Element == Index”的意思

时间:2021-10-09 21:58:33

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 ,其索引关联类型设置为Int。 Array能够符合您的协议,因为CountableRange (CountableRange .Iterator.Element)的迭代器元素和Index类型都是Int。

#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 ,其索引关联类型设置为Int。 Array能够符合您的协议,因为CountableRange (CountableRange .Iterator.Element)的迭代器元素和Index类型都是Int。