Using Swift 4, I have defined two structs in the same file, where one of them is private so this file is the only one that can access it. Also I'm relying on the struct's default/synthesized initializer i.e. I'm not explicitly defining one:
private struct A {
private let string: String
...
}
struct B {
func foo() {
let a = A(string: "bar")
...
}
}
However this will fail to compile with the following error:
'A' initializer is inaccessible due to 'private' protection level
I don't want to have A
accessible to other files, so I tried to work around it by making it fileprivate
(which should be equivalent to private
in this scenario), but the same compilation error will occur (and it still complains that the protection level is private
).
Is there a way to keep this struct fileprivate
and still get a synthesized initializer that exposes all uninitialized properties? i.e. A.init(string:)
It turns out that the "private access level" complaint was regarding the init
ializer, not the struct. The initializer's access level is only as accessible as the most accessible instance variable.
If I make the string
instance variable anything other than private
, the error goes away:
private struct A {
let string: String
// synthesized initializer:
// init(string: String)
}
So given that B
can now read A
's string
, it can also access A
's initializer.
If A
had another private
property though, then again its initializer would become private
:
private struct A {
let string: String
private let int: Int
// synthesized initializer:
// private init(string: String, int: Int)
...
}
You can define initializer. It will help you to keep this structure private
. The main problem is private let string
compiler automatically add initializer with private access level private init(string: String)
.
For fix you have to define your own initializer
private struct A {
private let string: String
fileprivate init(string: String) {
self.string = string
}
func foo() {}
}
struct B {
func bar() {
A(string: "baz").foo()
}
}
Or you can use fileprivate
access level for string
property. In this case you don't need initializer.
private struct A {
fileprivate let string: String
func foo() {}
}
struct B {
func bar() {
A(string: "baz").foo()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With