Reputation: 1191
Person.swift
class Person {
var name: String
init(name: String){
self.name = name
}
func greet() {
print("Hello, I am \(name)")
}
}
Workplace.swift
class WorkPlace {
var employees: [Person]
init(employees: [Person]) {
self.employees = employees
}
func greet() {
for employee in employees {
employee.customGreeting()
}
}
}
private extension Person {
func customGreeting() {
print("Hi")
}
}
Here I have a simple class called Person defined in Person.swift and a Workplace class defined in Workplace.swift.
The following is an excerpt taken from the Swift language guide (Access Control)
Alternatively, you can mark an extension with an explicit access-level modifier (for example, private) to set a new default access level for all members defined within the extension.
According to this I would expect the method customGreeting
in the private extension of Place not be visible inside Person.swift as it would be a private method and it is defined in a different file than the one the class is declared in, which is exactly what happens. I would also expect that method to not be visible inside Workplace.swift but it does. I am able to compile this code without any errors.
If I mark the method as private explicitly then it is not visible inside Workplace.swift. Shouldn't specifying the extension as private be enough to make the method private like it says in the language guide?
private extension Person {
private func customGreeting() {
print("Hi")
}
}
I know that this is a contrived example and I am just trying to get a clear picture of how access control works in swift.
Upvotes: 1
Views: 85
Reputation: 437632
The issue isn't that methods declared in a private extension available in other classes, but rather, more narrowly, that private
qualifier to an extension
produces fileprivate
behavior.
This is explicitly acknowledged in SE-0025, which says:
As before, an extension with an explicit access modifier overrides the default
internal
access by specifying a default scope. Therefore, within an extension markedprivate
, the default access level isfileprivate
(since extensions are always declared at file scope). This matches the behavior of types declared private at file scope.
This seems inconsistent with their broader statement:
... you can mark an extension with an explicit access-level modifier (for example,
private
) to set a new default access level for all members defined within the extension. This new default can still be overridden within the extension for individual type members.
While there is an inconsistency here, it would appear to be a conscious decision.
Upvotes: 2