我正在学习快速并正在使用Xcode。而且我总是深入研究定义。我看到了:
public protocol GeneratorType {
typealias Element
@warn_unused_result
public mutating func next() -> Self.Element?
}
Run Code Online (Sandbox Code Playgroud)
符合此协议的结构:
public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}
Run Code Online (Sandbox Code Playgroud)
我知道'Self'意味着返回符合类型。但是“ Self.Element”是什么意思?以及实现返回“ Elements._Element?”要求的函数,我看不到“ Elements._Element?” 等于“ Self.Element?”。有人可以向我解释吗?并告诉我更多有关此的信息。谢谢。
Self.Element指任何实现GeneratorType协议的类型都将声明为其类型Element别名的具体类型。
例如,在此斐波纳契数生成器中:
struct Fibonacci: GeneratorType {
typealias Element = Int
private var value: Int = 1
private var previous: Int = 0
mutating func next() -> Element? {
let newValue = value + previous
previous = value
value = newValue
return previous
}
}
Run Code Online (Sandbox Code Playgroud)
...实现GeneratorType协议并指出其类型Element别名(Int在这种情况下),这就是生成器next()将要返回的类型(嗯,实际上是该类型的可选类型)。
不过,在实现参数化协议时,您常常不必显式地指定类型别名,因为Swift足够聪明,可以为您推断出它们。例如,对于上面示例中的斐波那契数生成器,以下操作也可以做到:
struct Fibonacci: GeneratorType {
private var value: Int = 1
private var previous: Int = 0
mutating func next() -> Int? {
let newValue = value + previous
previous = value
value = newValue
return previous
}
}
Run Code Online (Sandbox Code Playgroud)
... Swift从签名中next()知道它返回了Int?,GeneratorType实现者也必须next()在他们的待办事项列表中,并且这些方法必须返回Element?类型。所以,斯威夫特只是把2和2在一起,并推断这Element?必须是同样的事情Int?,因此Element == Int。
对这个:
public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}
Run Code Online (Sandbox Code Playgroud)
这里我们有四件事:
IndexingGenerator,该通用类型采用称为的参数类型Elements。Elements类型具有必须实现Indexable协议的约束。Indexable的接口Elements,这是众所周知的IndexingGenerator通过点语法Elements._Element。Element与IndexingGenerator是相同的事情Elements._Element。因此,基本上上述声明等效于:
public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public typealias Element = Elements._Element
public init(_ elements: Elements)
public mutating func next() -> Element?
}
Run Code Online (Sandbox Code Playgroud)
最后,如果好奇为什么_Element而不是仅仅Element喜欢in GeneratorType,这就是他们在开源Swift仓库(在swift / stdlib / public / core / Collection.swift下)中写的内容:
_Element和下标的声明是一个技巧,用于打破Swift无法处理的循环一致性/推论。我们需要的不是aCollectionType.Generator.Element可以用作IndexingGenerator<T>的东西Element。在这里,我们安排CollectionType自身具有Element可以从其下标推断出的类型。理想情况下,我们希望将此限制Element为与相同CollectionType.Generator.Element,但今天我们无法表达它。
| 归档时间: |
|
| 查看次数: |
529 次 |
| 最近记录: |