[swift-users] still wrestling with a type conversion problem

David Baraff davidbaraff at gmail.com
Tue Jul 4 00:44:28 CDT 2017


I’m trying to provide some custom serialization from within a generic class.
(Briefly put, I want to automatically convert types like Set to an array upon serialization, and the reverse when I read it back.)

While trying things out, I was suprised by this:

public func encode<T>(_ value:T) -> Any {
    // print("Calling simple encoding for value")
    return value
}

public func encode<T>(_ value:Set<T>) -> Any {
    // print("Calling complex encoding for value")
    return value.map { $0 }
}

——————————————

The above transforms a Set to a list, but leaves everything else alone.  As expected:


print(type(of: encode(3)))			// Int
print(type(of: encode( Set([3,4,5]))))		// Array<Int>

Good.  But now I do this:

func genericEncode<T>(_ value:T) -> Any {
    return encode(value)
}

print(type(of: genericEncode(3)))		// Int
print(type(of: genericEncode( Set([3,4,5]))))	// Set<Int>

Aha.  Inside my generic function, I’ve “lost” the ability to overload based on type.  In retrospect, this is perhaps not to surprising.  Still, is there anyway that I can provide specialized versions of my functions which will take effect when called from *within* a generic function?

I’m basically trying to leave any type that is happy to go to/from UserDefaults alone, but for some set of types which isn’t JSON serializable (e.g. Set) I’d like to provide a simple pathway.  I don’t aim to hit every type in the world, but right now, I’m *totally* stymied when trying to do the serialization from within a generic class, as I lost any ability to specialize which function gets called.

[I’m from the C++ world of templates and metaprogramming, and I’m shifting from one set of constraints to another.  The swift type system with generics is cool and powerful, but man i’m still trying to really wrap my head around it.  Not that C++ was any easier…]




More information about the swift-users mailing list