Kotlin允许您扩展泛型类的具体实例。例如,假设我有一个扩展函数为Foo<Int>.bar()
和Foo<String>.bar()
的Foo
类
class Foo<T>(t: T) {
val a: String = "bar"
val b: Int = 111
}
fun Foo<Int>.bar() = a
fun Foo<String>.bar() = b
fun main(args: Array<String>) {
val stringBar: String = Foo(1).bar()
val intBar: Int = Foo("").bar()
}
可以在没有扩展函数的情况下实现此行为吗?如果可以,我如何将扩展函数转换为成员?可以在不重命名或更改类型签名的情况下实现吗?
发布于 2019-01-12 08:15:47
您可以使用具体化的泛型参数创建内联成员函数:
class Foo<T>(t: T) {
val a: String = "bar"
val b: Int = 111
inline fun <reified T, E> member(): E? {
var r: E? = null
when(T::class) {
String::class -> r = b as E
Int::class -> r = a as E
}
return r
}
}
fun main(args: Array<String>) {
val str = Foo(1).member<Int, String>()
val i = Foo("").member<String, Int>()
}
但是扩展函数更适合您的情况:它们是类型安全的,更简洁和可读性更好。
发布于 2019-01-12 18:40:43
不,这是不可能的(当前接受的答案与您的代码的行为完全不同)。
发布于 2019-01-12 18:41:46
使用反射,你不需要自己做类型和属性之间的映射。
成员函数propertyValue()
将返回具有泛型参数或null
类型的第一个属性的值。
class Foo {
val a: String = "bar"
val b: Int = 111
inline fun <reified T> propertyValue() = Foo::class.memberProperties.firstOrNull {
it.returnType == T::class.createType()
}?.get(this)
}
Foo().propertyValue<Int>()) // 111
Foo().propertyValue<String>()) // bar
Foo().propertyValue<Double>()) // null
当然,您也可以扩展这个函数,这样它就可以为您提供所需类型T
的所有属性的值(例如,如果您有多个Int
属性)。
https://stackoverflow.com/questions/54155416
复制