Kotlin - 类型参数的输出类型
Kotlin - output type from type parameter
我正在解析多个 CSV 文件,并希望为我的应用程序提供一些具有日志记录功能的通用解析器。是否可以给出一些通用的解决方案?
我的尝试是:
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")
}
}
}
}
但是,这不编译,kotlin 是否提供这样的功能来使函数 return type depend on type parameter?
您的解决方案几乎是正确的。唯一的问题是编译器不够聪明,无法理解您验证了 T
的类型并且您 return 是正确的转换器类型。您只需要将转换器转换为 T
:
return when (T::class) {
...
} as (String, String) -> T
此转换未经检查,这意味着编译器无法在运行时保证转换是安全的。但是,只要您 return 为 T
正确转换,这样的转换应该是安全的,您可以取消警告:
@Suppress("UNCHECKED_CAST")
return when (T::class) {
...
} as (String, String) -> T
我正在解析多个 CSV 文件,并希望为我的应用程序提供一些具有日志记录功能的通用解析器。是否可以给出一些通用的解决方案?
我的尝试是:
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")
}
}
}
}
但是,这不编译,kotlin 是否提供这样的功能来使函数 return type depend on type parameter?
您的解决方案几乎是正确的。唯一的问题是编译器不够聪明,无法理解您验证了 T
的类型并且您 return 是正确的转换器类型。您只需要将转换器转换为 T
:
return when (T::class) {
...
} as (String, String) -> T
此转换未经检查,这意味着编译器无法在运行时保证转换是安全的。但是,只要您 return 为 T
正确转换,这样的转换应该是安全的,您可以取消警告:
@Suppress("UNCHECKED_CAST")
return when (T::class) {
...
} as (String, String) -> T