在尝试实现将通用String转换为数字String扩展方法时,我开始使用reified关键字。以下代码可以编译并运行,但是在生产代码中使用它之前,我想对其进行改进:
inline fun <reified T> String.convertTo():T {
return when(T::class.simpleName){
Int::class.simpleName->{(this.toIntOrNull() ?: 0) as T}
Float::class.simpleName->{(this.toFloatOrNull() ?: 0f) as T}
Double::class.simpleName->{(this.toDoubleOrNull() ?: 0.0) as T}
else -> throw IllegalArgumentException("Can't convert type $(T::class.simpleName)")
}
}
我喜欢简洁的调用者代码:
val time:Int by lazy {((evaluateExpression("time").convertTo<Float>().times(1000f))).toInt()}
在这种情况下,我想做两件事:
1)我无法找到正确的语法将约束化的T限制为仅允许的类型-我想穷尽when条件并删除else-> throw
2)T :: class.java与其他类型的类类型(即Int :: class.java)无法正确比较,因此我不得不比较simpleName字符串-会更好吗?
这里是否有一种限制类型的方法,以及比较类类型的更好方法?
答案 0 :(得分:3)
仅当要处理的类型之间具有公共超类型时,才可以约束func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
}
。当然,您不能将超类型添加到内置的T
,Int
等类中,但是这些都是Float
,您可以使用:
Number
但是inline fun <reified T : Number> String.convertTo(): T
,Byte
和Long
也是如此,因此您仍然必须处理这些问题……但更重要的是,Short
只是一个抽象类而不是密封类(可以根据需要实现自己的类),因此Number
表达式在这种情况下无法穷尽。因此,不幸的是,您只需要保留when
分支即可。
对于这个问题的好消息,仅使用else
并比较::class
实例就可以了(我也删除了一些花括号):
KClass