Lets say I have some type, Property<Value>, and I want to type-erase this to AnyProperty so that I can now have Array<AnyProperty>, and then, have a typeUnerasedProperty variable on AnyProperty such that I can do:
func process(properties: [AnyProperty]) {
properties.map {
let typeUnerasedProperty = $0.unerase
process(property: typeUnerasedProperty)
}
}
func process<T>(property: Property<T>) where T == Int {
// do stuff when T is Int
}
func process<T>(property: Property<T>) where T == Double {
// do stuff when T is Double
}
func process<T>(property: Property<T>) {
// do stuff when T isn't Int or Double
}
Is this possible at all within Swift? Thanks.
Note: I have seen that we can save the type itself as a runtime variable but there doesn't seem to be a way to take advantage of that within the generics system, which seems to just be limited to only affecting static behaviors.
Seems the key to effective use of type erasure with generics in Swift is defining your API from the beginning in terms of actions as opposed to defining them in terms of data, so that later when you need to do type erasure, you can unerase things via capture semantics.
If you've already designed the API around data then it can become awfully hard to pry yourself free from using existentials.
There's no need to define ~= for types, you can use case is Int.Type: (or, with a value, case is Int:). Also, you are not really using _openExistential since at the end you are switching over the value type. You can simplify your process(properties:) function to be just:
func process(properties: [AnyProperty]) {
for property in properties {
switch property.value {
case let value as Int:
process(property: value)
case let value:
process(property: value)
}
}
}