swift-book
swift-book copied to clipboard
Access control modifiers on extensions that add protocol conformance
Location
No response
Description
I believe I've found some incorrect wording under the "Extensions" heading. Here's the line: "You can’t provide an explicit access-level modifier for an extension if you’re using that extension to add protocol conformance. Instead, the protocol’s own access level is used to provide the default access-level for each protocol requirement implementation within the extension." The first sentence is true. However, the second sentence is problematic.
If you extend a protocol and provide implementation for requirement(s), the implementations do indeed have the default access-level of the "original" protocol. However, when adding protocol conformance to a type via extension, implementations of protocol requirements receive their default access-level from the type that is being extended. Here is some code to illustrate this. In one file, let's write:
internal class SomeInternalClass { }
fileprivate protocol SomeFilePrivateProtocol {
func printHello()
}
// Extend the class and add protocol conformance
extension SomeInternalClass: SomeFilePrivateProtocol {
func printHello() {
print("Hello")
}
}
// Extend the protocol and implement a new method
extension SomeFilePrivateProtocol {
func printWorld() {
print("World")
}
}
And then, in a different swift file in the same project, let's write:
func printHelloAndWorld() {
SomeInternalClass().printHello() // OK
SomeInternalClass().printWorld() // Error: 'printWorld' is inaccessible due to 'fileprivate' protection level
}
If the second sentence from the Swift documentation was true, SomeInternalClass().printHello()
would trigger a compiler error: "'printHello' is inaccessible due to 'fileprivate' protection level". Instead, we see that the printHello()
method's default access-level is that of SomeInternalClass
, which is internal
.
Note that members which are implemented in the body of a protocol extension do indeed "inherit" the access-level of the protocol. I've illustrated this in the last line of code, which does trigger an error. We see that the printWorld()
method (which was implemented in the body of the extension of SomeFilePrivateProtocol
) has the default access-level of fileprivate
, which is the access-level of SomeFilePrivateProtocol
. Let me know if I'm not understanding or missing something.
Correction
No response