Assume we have the following example code:
protocol MyProtocol {
func someFunction()
}
public class MyClass {
}
public extension MyClass: MyProtocol {
func someFunction() {
print("hello")
}
}
Compiling the code above gives the following error:
Error: 'public' modifier cannot be used with extensions that declare protocol conformances
The same thing occurs if I mark the extension as private
. It seems as though you cannot set the access level of an extension that conforms to a protocol, regardless of what the access level is set to. Even setting the protocol declaration to public
or private
does not remove the error.
Question
What is the reasoning for Swift restricting an extension's access level in this way if it conforms to a protocol? If the protocol conformance is applied at the class level, there is no such restriction.
If I obey the compiler and remove the private
/public
designation, what is the access level of someFunction()
?
extension MyClass: MyProtocol {
func someFunction() {
print("hello")
}
}
I imagine in this case it would follow the original MyClass
implementation and be public
but I am not sure.
Is this behavior there because a protocol conformance in an extension means the entire class conforms to the protocol, and therefore it is redundant to re-specify the access level in the extension?
It's because it's impossible to conform to a protocol at any access level other than the access level of the protocol itself. In other words, if you have a
public
protocol, you cannot haveprivate
conformance to it. This is partially because protocol conformance is something that can be queried for at runtime (and therefore cannot differ between what module you're in, or be implemented twice in different files/modules), and partially because it would just plain be weird if a type conformed to a protocol in one file and didn't conform to that protocol when used in other files.As for your question of the access level of
someFunction
, it follows the same rules as any other function. Which is to say, it defaults tointernal
, unless the type itself has a lower access level. So in your case, ifMyClass
andMyProtocol
are bothpublic
, you can expect to get a compiler error telling you thatsomeFunction()
needs to be markedpublic
as well. But since it looks likeMyProtocol
is in factinternal
, omitting any access modifier works assomeFunction()
defaults tointernal
.