使用标准化类型的常规字符串扩展转换

时间:2018-06-19 12:24:00

标签: kotlin kotlin-reified-type-parameters

在尝试实现将通用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字符串-会更好吗?

这里是否有一种限制类型的方法,以及比较类类型的更好方法?

1 个答案:

答案 0 :(得分:3)

  1. 仅当要处理的类型之间具有公共超类型时,才可以约束func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { } 。当然,您不能将超类型添加到内置的TInt等类中,但是这些都是Float,您可以使用:

    Number

    但是inline fun <reified T : Number> String.convertTo(): T ByteLong也是如此,因此您仍然必须处理这些问题……但更重要的是,Short只是一个抽象类而不是密封类(可以根据需要实现自己的类),因此Number表达式在这种情况下无法穷尽。因此,不幸的是,您只需要保留when分支即可。

  2. 对于这个问题的好消息,仅使用else并比较::class实例就可以了(我也删除了一些花括号):

    KClass