[swift-evolution] Binding generic types using a metatype parameter
Joe Groff
jgroff at apple.com
Thu Mar 24 12:19:24 CDT 2016
> On Mar 23, 2016, at 11:29 AM, Joanna Carter <joanna at carterconsulting.org.uk> wrote:
>
> Hi Joe
>
>>
>> You can accomplish this with Swift today by casting your Any.Type to a Protocol.Type that provides an initializer:
>>
>> protocol Deserializable {
>> init(deserializedFrom stream: DeserializationStream)
>> }
>>
>> func deserializeValue(type type: Any.Type, from stream: DeserializationStream) -> Any? {
>> if let deserializableType = type as? Deserializable.Type {
>> return deserializableType.init(deserializedFrom: stream)
>> }
>> return nil
>> }
>
> Hmm… I've been playing with this for days now and, as useful as your code is for instantiating a given type, what I need to do is instantiate a generic type, bound to that given type.
>
> Something along the lines of…
>
> public protocol PropertyProtocol
> {
> var untypedValue: Any? { get }
> }
>
> public struct Property<PropertyType : Any>
> {
> public let info: PropertyInfo
>
> public var name: String
> {
> return info.name
> }
>
> public var displayName: String
> {
> return info.displayName
> }
>
> public var value: PropertyType?
>
> public init()
> {
> self.init(propertyInfo: PropertyInfo(), value: nil)
> }
>
> init(propertyInfo: PropertyInfo, value: PropertyType?)
> {
> self.value = value
>
> self.info = propertyInfo;
> }
>
> init(propertyInfo: PropertyInfo)
> {
> self.init(propertyInfo: propertyInfo, value: nil)
> }
>
> init(other: Property<PropertyType>)
> {
> self.init(propertyInfo: other.info, value: other.value)
> }
> }
>
> struct PropertyFactory
> {
> static func createBoundPropertywithValueType(valueType: Any.Type) -> PropertyProtocol
> {
> return Property<valueType>.init()
> }
> }
>
> Of course, Ive still got a lot of C# cruft in my thinking so I am more than willing to admit I may not be approaching this in the right way ;-)
Sorry for not getting back to you sooner. What's necessary here is a way to "open" the type of Any.Type, turning it back into something the compiler considers as a type instead of a value. This is something we've discussed having better support for, but right now there's only a sneaky way to do it using protocol extensions. If you constrain Property's type parameter to a protocol:
protocol PropertyType {}
struct Property<T: PropertyType>: PropertyProtocol {}
then you can add a static method to PropertyType in an extension, which can use Self as the opened dynamic type:
extension PropertyType {
private static func create() -> Property<Self> {
return Property<Self>.init()
}
}
and delegate to that extension method in your factory function:
struct PropertyFactory {
static func createBoundPropertywithValueType(valueType: PropertyType.Type) -> PropertyProtocol
{
return valueType.create()
}
}
-Joe
> struct PropertyFactory
> {
> static func createBoundPropertywithValueType(valueType: Any.Type) -> PropertyProtocol
> {
> return Property<valueType>.init()
> }
> }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160324/1753382a/attachment.html>
More information about the swift-evolution
mailing list