I'm playing with the Swift 5.7 new capabilities and I'm trying to implement some heterogeneous Sets.
I've reduced my code to this simple playground:
protocol Stuff: Hashable {
var identifier: String { get }
}
struct StuffA: Stuff {
let identifier: String
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
struct StuffB: Stuff {
let identifier: String
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
}
var arrayOfStuff: Array<any Stuff> = []
arrayOfStuff.append(StuffA(identifier: "a"))
arrayOfStuff.append(StuffB(identifier: "b"))
// Works like a charm
var setOfStuff: Set<any Stuff> = Set()
// error: Type 'any Stuff' cannot conform to 'Hashable'
setOfStuff.insert(StuffA(identifier: "a"))
setOfStuff.insert(StuffB(identifier: "b"))
The first try with Array<any Stuff> shows any can be used with a protocol to specify a generic constraint.
The second try fails because swift cannot checks the Hashable conformance. I know that Stuff does not conforms to Hashable, it only inherits from. But how do you tell the compiler that any Stuff will conform?
The issue is that Set requires a concrete type not an "any". This is a frustrating part of swift for now. You would have to make a type that conforms to the protocol, but still explicitly make it conform to a separate requirement/protocol?. I've recently run into the same situation in complex code and it's a real bummer. Basically you would have to make an arbitrary type that conforms to your protocol and the required "Hashable" In my case I made a LineItem wrapper that wraps a "any LineItemRepresentable(my protocol)" and conforms to the requirement that I couldn't just support by requiring the protocol to support it..
here's an example
protocol SomeProtocol {
var item {get set}
}
class MyClass: Hashable {
var wrappedValue: any SomeProtocol
// init...
var item: Item {
get {
wrappedValue.item
}
set {
wrappedValue.item = newValue
}
}
}
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