svanimpe
(Steven Van Impe)
1
Hi everone,
I'm struggling a bit with the following scenario:
I have a public function that should only accept specific types:
public func a<T: SpecificType>(p: T) { ... }
The types conforming to SpecificType are public types that are declared in the same module.
However, the requirements I need from SpecificType are only needed internally in the module, and I'd rather not make them public. But yet, the conformance to SpecificType should be public.
How do you recommend I implement this?
xwu
(Xiaodi Wu)
2
For what purpose do you need the conformance to be public?
You can separate those purposes out into a separate public base protocol refined by an internal protocol:
public protocol P {
// Public requirements.
}
internal protocol Q: P {
func f() -> Int
}
public struct S: Q {
// Note how this implementation isn’t exposed publicly.
internal func f() -> Int { 42 }
}
public func g<T: P>(_ t: T) {
guard let t = t as? Q else {
fatalError() // (…or, implement an alternative behavior.)
}
// This requires a recent version of Swift for implicit existential opening.
_g(t)
}
internal func _g<T: Q>(_ t: T) {
print(t.f())
}
g(S()) // 42
1 Like
You can try something like this:
public struct AnyP {
var impl: any P
}
internal protocol P {
…
}
public struct S {
var asP: AnyP { AnyP(impl: self) }
}
internal extension S: P {}
You could use underscored protocol requirements like SwiftUI does.
public func a<T: SpecificType>(p: T) { ... }
public protocol SpecificType {
func _foo(bar: Int) -> Int
func _baz(bar: Int) -> Int
var _fooBar: Int { get }
}
svanimpe
(Steven Van Impe)
5
Only because the protocol is used as a requirement in a public function.
Thanks. This is pretty much what I have now, I was just wondering if there's a "cleaner" way to do this (without the cast). But so far, it's still my preferred solution.