gpt4 book ai didi

swift - 协议(protocol)中的 self

转载 作者:可可西里 更新时间:2023-11-01 00:51:46 25 4
gpt4 key购买 nike

我正在学习 Swift 并使用 Xcode。我总是深入研究定义。我看到了:

public protocol GeneratorType {
typealias Element
@warn_unused_result
public mutating func next() -> Self.Element?
}

一个符合这个协议(protocol)的结构体:

public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}

我知道“Self”意味着返回一致的类型。但是“Self.Element”是什么意思?以及实现返回“Elements._Element?”要求的函数,我看不到“Elements._Element?”等于“Self.Element?”。谁能给我解释一下?告诉我更多相关信息。谢谢。

最佳答案

Self.Element指的是任何类型实现 GeneratorType 的具体类型协议(protocol)将声明为它的 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
}
}

... 你实现 GeneratorType协议(protocol)并指出它的 Element 是什么typealias(在本例中为 Int),这就是生成器的 next() 的类型将返回(好吧,实际上是那种类型的可选)。

不过,在实现参数化协议(protocol)时,您通常不必显式指定类型别名,因为 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
}
}

... Swift 从 next() 的签名中知道它返回 Int? ,那GeneratorType实现者还必须有 next()在他们的待办事项列表中,并且这些方法必须返回 Element?类型。所以,Swift 只是将 2 和 2 放在一起,推断 Element?必须与 Int? 相同,因此 Element == Int .


关于这个:

public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}

这里我们有四件事正在进行:

  • 我们声明通用类型IndexingGenerator它采用名为 Elements 的参数类型.
  • Elements type 有一个必须实现的约束 Indexable协议(protocol)。
  • 我们实现的生成器应该返回可通过 Indexable 访问的类型的值Elements的界面,这是已知的 IndexingGenerator通过点语法为 Elements._Element .
  • Swift 推断 ElementIndexingGeneratorElements._Element 相同.

所以,基本上上面的声明等同于:

public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public typealias Element = Elements._Element
public init(_ elements: Elements)
public mutating func next() -> Element?
}

最后,如果好奇为什么_Element而不仅仅是 Element就像在GeneratorType ,这是他们在 open-source Swift repository 中写的内容(在 swift/stdlib/public/core/Collection.swift 下):

The declaration of _Element and subscript here is a trick used to break a cyclic conformance/deduction that Swift can't handle. We need something other than a CollectionType.Generator.Element that can be used as IndexingGenerator<T>'s Element. Here we arrange for the CollectionType itself to have an Element type that's deducible from its subscript. Ideally we'd like to constrain this Element to be the same as CollectionType.Generator.Element, but we have no way of expressing it today.

关于swift - 协议(protocol)中的 self ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35505001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com