[swift-evolution] Generic Subscripts
Brent Royal-Gordon
brent at architechies.com
Fri Jan 13 20:33:57 CST 2017
> On Jan 13, 2017, at 9:50 AM, John McCall via swift-evolution <swift-evolution at swift.org> wrote:
>
> I'm also not sure we'd ever want the element type to be inferred from context like this. Generic subscripts as I see it are about being generic over *indexes*, not somehow about presenting a polymorphic value.
I think I have a pretty good use case for generic element types: you may want an index to carry the type of its element. For example, suppose you want to have a sort of dictionary whose keys are unique instances of a key class, and whose value type depends on the key instance:
struct TypedDictionary {
final class Key<T>: Hashable {
init(of type: T.Type) {}
var hashValue: Int { return ObjectIdentifier(self).hashValue }
static func == (lhs: Key, rhs: Key) { return lhs === rhs }
}
private var storage: [AnyHashable: Any] = [:]
subscript<T>(key: Key<T>) -> T? {
get {
return storage[key] as! T?
}
set {
storage[key] = newValue as Any?
}
}
}
let messageKey = TypedDictionary.Key(of: String.self)
let answerKey = TypedDictionary.Key(of: Int.self)
var myDict = TypedDictionary()
myDict[messageKey] = "Hello, world!"
myDict[answerKey] = 42
I've wanted to do things like this in at least three or four different contexts; you could even imagine reflection being implemented this way, with typed `PropertyKey`s and a subscript available on all instances. You can work around it with methods, but it always feels unnatural, with vacuous method names like `value(for:)`.
I do agree that it is probably useless and certainly a little dangerous to have a generic parameter that's completely inferred from the return value, but you could make the same argument for methods, and yet we allow them there.
--
Brent Royal-Gordon
Architechies
More information about the swift-evolution
mailing list