I am parsing multiple CSV files and would like to provide my application with some generic parsers with logging capabilities. Is it possible to give some generic solution for it?
My try to do that is:
interface Converter<out T> {
fun convert(fieldName: String, value: String): T?
}
object DoubleMapper : Converter<Double> {
private val log = LoggerFactory.getLogger(this::class.java)
override fun convert(fieldName: String, value: String): Double {
log.info("Converting $fieldName: $value to Double")
return 123.3
}
}
object ConverterProvider {
private val log = LoggerFactory.getLogger(ConverterProvider::class.java)
inline fun <reified T : Any> getConverter(): (String, String) -> T {
return when (T::class) {
Double::class -> DoubleMapper::convert
Int::class -> IntMapper::convert
else -> {
throw java.lang.RuntimeException("We do not have mapper")
}
}
}
}
However, this does not compile, does kotlin provide such capabilities to have function return type depend on type parameter?
CodePudding user response:
Your solution is almost correct one. The only problem is that the compiler is not smart enough to understand that you verified the type of T
and you return the right type of the converter. You just need to cast the converter to T
:
return when (T::class) {
...
} as (String, String) -> T
This cast is unchecked, meaning that the compiler can't guarantee at runtime that the cast is safe. However, as long as you return correct converter for the T
, such cast should be safe and you can just suppress the warning:
@Suppress("UNCHECKED_CAST")
return when (T::class) {
...
} as (String, String) -> T