admin管理员组文章数量:1415119
Trying to get list item of certain type passed in function. This code works as expected, but it looks not so good. Can I check classes types into firstOrNull
lambda directly, instead of comparing names?
fun <T: TripManagerModule> getModule(moduleType: KClass<T>): T? {
return modules
.firstOrNull { it::class.simpleName == moduleType.simpleName }
?.let { it as? T } //Warning here: "Unchecked cast: TripManagerModule to T"
}
val module = getModule(TripArrivalDelayManager::class)
Trying to get list item of certain type passed in function. This code works as expected, but it looks not so good. Can I check classes types into firstOrNull
lambda directly, instead of comparing names?
fun <T: TripManagerModule> getModule(moduleType: KClass<T>): T? {
return modules
.firstOrNull { it::class.simpleName == moduleType.simpleName }
?.let { it as? T } //Warning here: "Unchecked cast: TripManagerModule to T"
}
val module = getModule(TripArrivalDelayManager::class)
Share
Improve this question
asked Feb 12 at 21:20
Konstantin KonopkoKonstantin Konopko
5,4344 gold badges39 silver badges66 bronze badges
0
2 Answers
Reset to default 2You can utilize filterIsInstance()
that preserves the type of the list:
fun <T : TripManagerModule> getModule(moduleType: KClass<T>): T? =
modules
.filterIsInstance(moduleType.java)
.firstOrNull()
You don't need to cast anymore, it will already be of the correct type.
And if you want to get rid of the parameter you can make the function inline:
inline fun <reified T : TripManagerModule> getModule(): T? =
modules
.filterIsInstance<T>()
.firstOrNull()
You can then call it like this
val module = getModule<TripArrivalDelayManager>()
or let the compiler infer the type, for example like this:
val module: TripArrivalDelayManager? = getModule()
You can compare the class objects directly. From KClass::equals (specifically the JVM docs):
Returns true if this KClass instance represents the same Kotlin class as the class represented by other. On JVM this means that all of the following conditions are satisfied:
other has the same (fully qualified) Kotlin class name as this instance.
other's backing Class object is loaded with the same class loader as the Class object of this instance.
If the classes represent Array, then Class objects of their element types are equal.
For example, on JVM, KClass instances for a primitive type (int) and the corresponding wrapper type (java.lang.Integer) are considered equal, because they have the same fully qualified name "kotlin.Int".
And since you have the KClass
, you can use it to cast the element to avoid the unchecked cast warning.
fun <T : TripManagerModule> getModule(moduleType: KClass<T>): T? {
return modules.firstOrNull { it::class == moduleType }?.let(moduleType::cast)
}
That will return the first element whose class is exactly moduleType
(or null
if no such element exists). However, if you want the first instance of moduleType
, then you can use isInstance.
fun <T : TripManagerModule> getModule(moduleType: KClass<T>): T? {
return modules.firstOrNull(moduleType::isInstance)?.let(moduleType::cast)
}
And if you want, you can add the following convenience inline function:
inline fun <reified T : TripManagerModule> getModule() = getModule(T::class)
Which would let you call the function like:
val module = getModule<SomeModuleType>()
Instead of only like:
val module = getModule(SomeModuleType::class)
本文标签: androidKotlin Get list item of certain type passed in functionStack Overflow
版权声明:本文标题:android - Kotlin: Get list item of certain type passed in function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745201538a2647400.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论