You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin多平台项目中Indriya库泛型与函数遮蔽问题求助

问题解决:Kotlin多平台调用Indriya库时单位转换方法匹配错误

问题根源

由于unitFormat.parse()返回Unit<?>无界通配泛型类型,编译期无法确定其具体量纲,导致调用fromQuantity.to(toUnit)时,Kotlin会优先匹配标准库的to扩展函数,而非Indriya中ComparableQuantity的Java实例方法to(Unit<Q>)。


解决方案1:显式类型转换(安全可行)

因为运行时可确保源单位与目标单位属于同一量纲(否则Indriya会抛出运行时异常),可以通过unchecked cast消除泛型擦除的影响,让编译器正确识别Java方法:

import tech.units.indriya.format.SimpleUnitFormat
import tech.units.indriya.quantity.Quantities
import javax.measure.format.UnitFormat
import tech.units.indriya.quantity.ComparableQuantity

class AndroidPlatform : Platform {
    override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
    private val unitFormat: UnitFormat = SimpleUnitFormat.getInstance()

    @Suppress("UNCHECKED_CAST")
    override fun convert(value: Double, sourceUnit: String, targetUnit: String): Double {
        val fromUnit = unitFormat.parse(sourceUnit) as javax.measure.Unit<Any>
        val fromQuantity = Quantities.getQuantity(value, fromUnit) as ComparableQuantity<Any>
        val toUnit = unitFormat.parse(targetUnit) as javax.measure.Unit<Any>

        val result = fromQuantity.to(toUnit)
        return result.value.toDouble()
    }
}

actual fun getPlatform(): Platform = AndroidPlatform()
  • @Suppress("UNCHECKED_CAST")用于消除编译期的unchecked cast警告,只要确保输入的单位属于同一量纲,该转换就是安全的。
  • 如果单位量纲不匹配,Indriya会在运行时抛出IllegalArgumentException,可根据业务需求添加异常捕获逻辑。

解决方案2:直接使用预定义单位(适用于标准单位场景)

如果你的转换仅涉及Indriya预定义的标准单位,可以直接调用Units类的常量,避免parse方法带来的泛型问题:

import tech.units.indriya.unit.Units

// 示例:米转千米
val fromUnit = Units.METRE
val toUnit = Units.KILOMETRE
val fromQuantity = Quantities.getQuantity(1000.0, fromUnit)
val result = fromQuantity.to(toUnit) // 正确调用Java方法

这种方式无需处理泛型转换,代码更简洁,但仅支持库中预定义的标准单位。


内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:07:33