Danny
February 21, 2025, 12:06am
1
This is related to "How do you forward opaque inputs to default implementation outputs without a derived protocol? " but this is a simpler question. (Use case for this, here. )
You have a protocol requirement that uses an associated type.
protocol Protocol {
associatedtype Property
var property: Property { get }
}
You want to use an opaque value to define Property
.
var opaqueValue: some Any {
"This is from a 3rd party API and must be opaque."
}
It cannot be done directly.
struct Conformer: Protocol { // Type 'Conformer' does not conform to protocol 'Protocol'
init() { property = opaqueValue }
var property: Property // Reference to invalid associated type 'Property' of type 'Conformer'
}
But it can be done via another protocol. Is that really the simplest solution?
struct Conformer {
init() { property = Self._property() }
var property: Property
}
private protocol _Conformer: Protocol where Property == OpaqueProperty {
associatedtype OpaqueProperty
static func _property() -> OpaqueProperty
}
extension Conformer: _Conformer {
static func _property() -> some Any { opaqueValue }
}
Clarification : It must be possible to refer to the resulting type, such as for defining a variable of its type.
struct Requirement {
let requirement: Conformer
}
vanvoorden
(Rick van Voorden)
February 21, 2025, 12:08am
2
Have you tried typealias
?
Ahh… nevermind… you need to start with a some
.
vanvoorden
(Rick van Voorden)
February 21, 2025, 12:15am
4
struct Conformer<T>: P {
var property: T
init(property: T) {
self.property = property
}
}
let _ = Conformer(property: opaqueValue)
Are you blocked from making conformer
generic over Property
?
Danny:
It cannot be done directly.
struct Conformer: Protocol { // Type 'Conformer' does not conform to protocol 'Protocol'
init() { property = opaqueValue }
var property: Property // Reference to invalid associated type 'Property' of type 'Conformer'
}
Why not var property: some Any = opaqueValue
?
4 Likes
Danny
February 21, 2025, 12:39am
6
Yes. I added a Clarification about this at the end.
Danny
February 21, 2025, 12:58am
7
I didn't even know that would work, given that
var property = opaqueValue
…which I had tried, did not work. That feels pretty weird. Is it intended?
Property initializers do not support arguments. Got some magic to fix that too?
typealias Input = Void // Input type doesn't matter.
func opaqueValue(_ input: Input) -> some Any {
"This is from a 3rd party API and must be opaque."
}
struct Conformer {
init(_ input: Input) { property = Self._property(input) }
var property: Property
}
private protocol _Conformer: Protocol where Property == OpaqueProperty {
associatedtype OpaqueProperty
static func _property(_ input: Input) -> OpaqueProperty
}
extension Conformer: _Conformer {
static func _property(_ input: Input) -> some Any { opaqueValue(input) }
}