[Docs] Edits for educational note on PATs (#33736)

* [Docs] Minor edits for educational note on PATs

* Adopt reviewer feedback on wording

Co-authored-by: Owen Voorhees <owenvoorhees@gmail.com>

* Revert a capitalization change

* [Docs] Further revisions based on reviewer feedback for educational note on PATs

Co-authored-by: Owen Voorhees <owenvoorhees@gmail.com>
This commit is contained in:
Xiaodi Wu
2021-03-19 23:46:33 -04:00
committed by GitHub
parent 2f6fb2dd45
commit ae35835008

View File

@@ -1,24 +1,28 @@
# Using Protocols with `Self` or Associated Type Requirements # Using Protocols with `Self` or Associated Type Requirements
Protocols in Swift may be used as types, as part of a generic constraint, or as part of an opaque result type. Protocols in Swift may be used as types, as part of a generic constraint, or as part of an opaque result type.
```swift ```swift
// CustomStringConvertible can be used as a type. // `CustomStringConvertible` can be used as a type.
func foo(bar: CustomStringConvertible) { /* ... */ } func foo(bar: CustomStringConvertible) { /* ... */ }
// ...or as a generic constraint on 'T'. // ...or as a generic constraint on `T`.
func bar<T: CustomStringConvertible>(baz: T) { /* ... */ } func bar<T: CustomStringConvertible>(baz: T) { /* ... */ }
// ...or as part of an opaque result type. // ...or as part of an opaque result type.
func baz() -> some CustomStringConvertible { /* ... */ } func baz() -> some CustomStringConvertible { /* ... */ }
``` ```
While all Swift protocols can be used as generic constraints and as part of opaque result types, not all protocols can be used as types in general. Specifically, if a protocol has a requirement which references `Self` or an associated type, it cannot be used as a type. One such protocol is `Identifiable`, which has the requirement `var id: ID { get }`, where `ID` is an associated type. As a result, the following code is not allowed: While all Swift protocols can be used as generic constraints and as part of opaque result types, not all protocols can be used as types. Specifically, if a protocol has a requirement which references `Self` (in contexts other than a function's return type) or an associated type, it cannot be used as a type. For example, the protocol `Equatable` requires `static func == (lhs: Self, rhs: Self) -> Bool`, and the protocol `Identifiable` requires `var id: ID { get }`, where `ID` is an associated type. As a result, the following code is not allowed:
```swift ```swift
func foo(bar: Equatable) { /* ... */ }
// error: protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements
func foo(bar: Identifiable) { /* ... */ } func foo(bar: Identifiable) { /* ... */ }
// error: protocol 'Identifiable' can only be used as a generic constraint because it has Self or associated type requirements // error: protocol 'Identifiable' can only be used as a generic constraint because it has Self or associated type requirements
``` ```
Protocols like `Identifiable` which have `Self` or associated type requirements cannot be used as types because such types would rarely be useful in practice. They would be unable to allow use of `Self` or associated type requirements like `var id: ID { get }` because the associated type is not specified. These `Self` or associated type requirements cannot be used via a protocol type because they do not have a well-defined meaning without a concrete conforming type. Therefore, Swift does not support the use of protocols as types if they have such `Self` or associated type requirements, since those types would be able to present only a potentially unusable subset of the interface required for instances of concrete conforming types.
When working with protocols having `Self` or associated type requirements constrained generics, opaque result types, or manual type erasure is sufficient to support most use cases. To learn more, see the [Protocols](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html), [Generics](https://docs.swift.org/swift-book/LanguageGuide/Generics.html), and [Opaque Types](https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html) sections of _The Swift Programming Language_. When working with protocols that have `Self` or associated type requirements, most use cases can be supported by constrained generics, opaque result types, or manual type erasure. To learn more, see the sections on [protocols](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html), [generics](https://docs.swift.org/swift-book/LanguageGuide/Generics.html), and [opaque types](https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html) in _The Swift Programming Language_.