Kotlin 无缘无故地尝试将 Double 转换为 Int?

Kotlin tries to cast a Double to an Int for no reason?

美好的一天,

我正在尝试让这段代码工作:

fun <T: Comparable<T>> getExtreme(data: JSONArray, searchKeyword: String, compareValue: T, define: CompareOp): T {
    val tmpFun: (T, T) -> Boolean = when (define) {
        CompareOp.LESSER -> { a: T, b: T -> a < b }
        CompareOp.GREATER -> { a: T, b: T -> a > b }
    }

    var extremeAmount: T = compareValue

    for (hourlyIndex in 0 until data.length()) {
        val dataSet: JSONObject = data.getJSONObject(hourlyIndex)
        val hourlyUvi: T = dataSet.get(searchKeyword) as T
        Log.d("MATH FUNC", "$hourlyUvi")
        if (tmpFun(hourlyUvi, extremeAmount)) extremeAmount = hourlyUvi
    }
    return extremeAmount
}

但是由于某种原因它总是抛出这个异常:

我认为错误是什么,它每次读取一个整数时都会自动将其转换为 Int,而不是保留在我指定的 T 中。这段代码工作正常,并且在没有这一行的情况下几乎完美无缺:
if (tmpFun(hourlyUvi, extremeAmount)) extremeAmount = hourlyUvi
如果那是错误,我如何强制执行我的 T 而不是它自己的定义,它为什么这样做,或者错误是否出在其他地方?

有几个 built-in 类型转换器,如 jsonObj.getDouble(key)jsonObj.getInt(key),当 JSON 输入字符串是数字类型(如整数)并且您想要不同的数字类型作为输出(例如双精度)。

但是,将其与通用输出类型 T 一起使用并不那么简单。如果你真的需要使用泛型,你可以写一个泛型 JSONObject to T converter。如果 JSBONObject 不是数字类型或可以解析为数字类型的字符串,getX 方法将抛出。

确保转换器涵盖了所有你想使用的可能的数字类型,否则它会落到最后一个案例和return测试值。你必须传入一个 T 类型的对象来进行类型检查,即使它没有被使用。

fun <T> jsonObjToType(o: JSONObject, arg: String, test: T): T {
    return when(test) {
        is Double -> o.getDouble(arg) as T
        is Int -> o.getInt(arg) as T
        is Float -> o.getDouble(arg).toFloat() as T
        is Long -> o.getLong(arg) as T
        else -> test // will never hit this as long 
                     // as all possible T types are covered above
    }
}

并在您的函数中使用它

val hourlyUvi: T = jsonObjToNumericType(dataSet, searchKeyword, extremeAmount)
if (tmpFun(hourlyUvi, extremeAmount)) extremeAmount = hourlyUvi

注意:当您使用 Int 或 Long 类型时,如果数组中有浮点值,它们将被截断为整数值。在几乎所有情况下,最好只为双打编写此函数,而不是作为 T 的泛型来适当处理所有情况。