我是Kotlin的新手,我试图编写一个简单的泛型方法,但它无法编译
inline fun <T:Number> List<T>.firstOrZero() : T { if (isEmpty()) return 0 // this line doesn't compile else return this[0] }
有办法吗?
xjreopfe1#
您需要为您想要支持的每个Number子类处理它。比如像这样
Number
inline fun <reified T : Number> List<T>.firstOrZero(): T { return (if (isEmpty()) when (T::class) { Int::class -> 0 Double::class -> 0.0 Float::class -> 0f BigInteger::class -> BigInteger.ZERO else -> throw RuntimeException() } else this[0]) as T }
dfuffjeb2#
我们无法在Kotlin中以完全通用的方式处理这种情况。无论我们选择什么解决方案,我们都必须分别处理每种类型的Number。因此,我建议不要使用泛型函数,而是使用多个重载:
fun List<Int>.firstOrZero() = if (isEmpty()) 0 else this[0] fun List<Long>.firstOrZero() = if (isEmpty()) 0 else this[0]
这可能比使用反射的泛型解决方案更快,因为类型是在编译时而不是运行时解析的。如果你有更多这样的病例,你的病例就更复杂,等等如果你担心代码重复,你可以内联通用代码:
fun List<Int>.firstOrZero() = firstOrDefault { 0 } fun List<Long>.firstOrZero() = firstOrDefault { 0 } private inline fun <T:Number> List<T>.firstOrDefault(default: () -> T) : T { if (isEmpty()) return default() else return this[0] }
但对于firstOrZero()的具体情况,我认为这是一个矫枉过正。
firstOrZero()
zpgglvta3#
您需要确保返回类型与预期类型匹配。因为定义了泛型类型'T',所以需要返回'T',它扩展了'Number'。
inline fun <T : Number> List<T>.firstOrZero(): T { if (isEmpty()) return 0 as T else return this[0] }
4bbkushb4#
有一种方法可以做到这一点。可以使用default关键字为T类型参数提供默认值。在这种情况下,默认值为0。下面的代码将编译并运行:
T
inline fun <T:Number> List<T>.firstOrZero() : T { if (isEmpty()) return 0.default<T>() // this line compiles else return this[0] }
default关键字可用于为任何类型参数提供默认值。当您要确保方法或属性始终具有值时,即使未指定类型参数,这也很有用。在这种情况下,default关键字用于为T类型参数提供默认值0。这意味着如果没有指定T类型参数,则该方法将返回0。下面是如何使用firstOrZero()方法的示例:
val list = listOf(1, 2, 3) val firstNumber = list.firstOrZero() println(firstNumber) // prints 1 val emptyList = emptyList<Int>() val firstNumberInEmptyList = emptyList.firstOrZero() println(firstNumberInEmptyList) // prints 0
4条答案
按热度按时间xjreopfe1#
您需要为您想要支持的每个
Number
子类处理它。比如像这样dfuffjeb2#
我们无法在Kotlin中以完全通用的方式处理这种情况。无论我们选择什么解决方案,我们都必须分别处理每种类型的
Number
。因此,我建议不要使用泛型函数,而是使用多个重载:
这可能比使用反射的泛型解决方案更快,因为类型是在编译时而不是运行时解析的。
如果你有更多这样的病例,你的病例就更复杂,等等如果你担心代码重复,你可以内联通用代码:
但对于
firstOrZero()
的具体情况,我认为这是一个矫枉过正。zpgglvta3#
您需要确保返回类型与预期类型匹配。
因为定义了泛型类型'T',所以需要返回'T',它扩展了'Number'。
4bbkushb4#
有一种方法可以做到这一点。可以使用default关键字为
T
类型参数提供默认值。在这种情况下,默认值为0。下面的代码将编译并运行:default关键字可用于为任何类型参数提供默认值。当您要确保方法或属性始终具有值时,即使未指定类型参数,这也很有用。
在这种情况下,default关键字用于为
T
类型参数提供默认值0。这意味着如果没有指定T
类型参数,则该方法将返回0。下面是如何使用
firstOrZero()
方法的示例: