Skip to content

Instantly share code, notes, and snippets.

@inamiy
Created November 7, 2019 15:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inamiy/de70f5b107af7b4c6d64c317c7d19930 to your computer and use it in GitHub Desktop.
Save inamiy/de70f5b107af7b4c6d64c317c7d19930 to your computer and use it in GitHub Desktop.
Private conformance to public protocol without making internal members / methods public.
// Private Conformance (Generic Manifesto)
// https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#private-conformances
//
// > Right now, a protocol conformance can be no less visible than the minimum of the conforming type's access and the protocol's access.
// > Therefore, a public type conforming to a public protocol must provide the conformance publicly.
// > The main problem with private conformances is the interaction with dynamic casting
public protocol PublicProtocol {
var foo: String { get }
}
// OK
internal struct Struct: PublicProtocol {
internal var foo: String = ""
}
// ERROR: Property 'foo' must be declared public because it matches a requirement in public protocol 'PublicProtocol'
//public struct PublicStruct: PublicProtocol {
// fileprivate var foo: String = ""
//}
// ERROR: This doesn' work too.
//internal extension PublicStruct: PublicProtocol {
// var foo: String { "" }
//}
// Goal: always keep `foo` as private, but conform to `PublicProtocol` for internal usage only.
public struct PublicStruct {
internal var foo: String = ""
}
// Solution:
// Add **internal proxy** that conforms to `PublicProtocol` instead.
// Inside the same module, use this type to gain `PublicProtocol` behavior.
// For the outside of the module, `PublicStruct` is the only public as usual.
internal struct PrivateProxy: PublicProtocol {
internal var inner: PublicStruct
// Forward all protocol requirements...
internal var foo: String { // But this is still exposing `foo`...
inner.foo
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment