Skip to content

Commit cd3440e

Browse files
authored
Merge pull request swiftlang#33832 from xwu/existential-edu-part-2
[docs] Rework educational note on protocol type non-conformance, part 2
2 parents 03adbe3 + 7f16910 commit cd3440e

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

userdocs/diagnostics/protocol-type-non-conformance.md

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,41 @@ In general, any initializers, static members, and associated types required by a
5252

5353
Currently, even if a protocol `P` requires no initializers or static members, the existential type `P` does not conform to `P` (with exceptions below). This restriction allows library authors to add such requirements (initializers or static members) to an existing protocol without breaking their users' source code.
5454

55+
## Exceptions
56+
57+
When used as a type, the Swift protocol `Error` conforms to itself; `@objc` protocols with no static requirements can also be used as types that conform to themselves.
58+
59+
## Alternatives
60+
5561
Concrete types that _do_ conform to protocols can provide functionality similar to that of existential types. For example, the standard library provides the `AnyHashable` type for `Hashable` values. Manual implementation of such __type erasure__ can require specific knowledge of the semantic requirements for each protocol involved and is beyond the scope of this discussion.
5662

57-
For more on using existential types, see [Protocols as Types](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID275) in _The Swift Programming Language_.
63+
In certain scenarios, you might avoid any need for manual type erasure by reworking generic APIs to use existential types instead:
5864

59-
## Exceptions
65+
```swift
66+
func declareAnimalSpeciesDynamically(_ animal: Animal) {
67+
animal.makeNoise()
68+
print("My species is known as \(type(of: animal).species)")
69+
}
70+
71+
declareAnimalSpeciesDynamically(animal)
72+
// Prints:
73+
// "Meow"
74+
// "My species is known as Felis catus"
75+
```
76+
77+
(Note that there is a distinction between the _static_ type of a value as given by the generic parameter `T` and the _dynamic_ type of a value obtained by invoking `type(of:)`. For example, the static type of `animal` is `Animal`, while its dynamic type is `Cat`. Therefore, the two functions `declareAnimalSpecies(_:)` and `declareAnimalSpeciesDynamically(_:)` are not exact replacements of each other.)
78+
79+
The same technique might be applicable to members of generic types:
80+
81+
```swift
82+
// Instead of...
83+
struct Habitat<T: Animal> {
84+
var animal: T
85+
}
86+
// ...consider:
87+
struct Habitat {
88+
var animal: Animal
89+
}
90+
```
6091

61-
The Swift protocol `Error` has no required members and, when used as a type, conforms to itself; `@objc` protocols with no static requirements can also be used as types that conform to themselves.
92+
For more on using existential types, see [Protocols as Types](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html#ID275) in _The Swift Programming Language_.

0 commit comments

Comments
 (0)