Reputation: 7613
access level confusion in swift.
I was experimenting with swift access level for class and their data member and subclasses. and below code worked fine in playground without any error.
i thought we can only give <= access level to class data members. (ie. if class is internal then its data member or functions should only be internal or private or file private.)
but below code work without any error in playground.
1.
public struct Student{
private var studentId : String
}
2.
open class Employee{
open var EmployeeId : String?
}
3.
private class CompanyEmployee : Employee{
}
4.
internal class Animal{
public var no_of_legs : Int?
open var name : String?
}
5.
fileprivate class Shape{
public var shape_type : String?
}
6.
private class Point{
public var x : Int?
public var y : Int?
}
7.
fileprivate class SpecificPoint : Point{
}
Upvotes: 0
Views: 226
Reputation: 385930
The default access level is internal
. If you specify a narrower access level (fileprivate
or private
) on your type, the access level of its members can only be as wide as the type's access level. But you don't want to have to write that narrower access level on every member of the type.
That is, you want to be able to write this:
// Only specify narrower access for the type, not for the type's members.
fileprivate struct Point {
var x: Double
var y: Double
}
You don't want to have to write this:
// Specify narrower access for the type and its members.
fileprivate struct Point {
fileprivate var x: Double
fileprivate var y: Double
}
But the default access level is internal
. So, Swift automatically “clamps” a member's access level to the narrower of the member's specified or default access level and its container's access level.
Yes, there are other ways Swift could handle this (for example, by only clamping when the unwritten default internal
was used), but this is how it was implemented. It can't be changed now without breaking existing source code.
It is worth noting that a type or a member can have a narrow access level but in fact be more accessible through a protocol conformance. Consider this example:
protocol P {
var x: Int { get }
}
fileprivate struct S: P {
var x: Int
}
func make() -> P { return S(x: 100) }
In this example, make
and P
have the default internal
access level, while the type S
explicitly has fileprivate
access level and its member x
has effective fileprivate
access level.
However, from any other file in the module, you can call make()
. You'll get an S
back, but you can only treat it is a P
. Since it is a P
, you can read its x
property, even though the x
property of S
has effective access level fileprivate
.
Upvotes: 1