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
的泛型来适当处理所有情况。
美好的一天,
我正在尝试让这段代码工作:
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
的泛型来适当处理所有情况。