I am writing an interface to Someone Else's Code (SEC), and I have a long list of functions more or less like this:
public func readString(_ row: Row, columnName: String) -> String? {
return SEC.getString(row, columnName)
}
public func readInt(_ row: Row, columnName: String) -> Int? {
return SEC.getInt(row, columnName)
}
And so on.
What I would like to do is have a single function:
public func read<T>(_ row: Row, columnName: String) -> T? {
// call correct SEC.get* method
}
I tried a simple switch statement on T
and on T.Type
, but no dice. I also tried a modified version of the above:
public func read<T: ReadableType>(_ row: Row, columnName: String) -> T? {
let getter = T.getterMethod
return getter(row, columnName)
}
Where I could create an enum
of the metatypes that had SEC.get*
functions, and extend it to return the proper getter method. This to me seemed ideal. Alas:
public enum ReadableTypes {
case String.Type // nope
case Int.self // also nope
}
I'm not sure what else to try; it's not the end of the world if I simply have a dozen read* methods, but the code that calls this method could be so dang tight if I could make it generic.
You can individually test to see what type the generic placeholder represents like this:
The same sort of test can be done in a
switch..case
statement.Assuming
SEC
is of typeSECType
what I'd do is extendSECType
to have a genericget
method that keys on the return type:Now you can write your own
read
function like:Of course you can skip doing the
extension
and just do a generic function with aswitch
. However, it's harmless to add the method to the type and it makes sense for the type to have a generic method like this.