gpt4 book ai didi

generics - 如何在 Kotlin 中使用泛型创建映射?

转载 作者:行者123 更新时间:2023-12-03 07:11:18 28 4
gpt4 key购买 nike

我需要创建一个映射,其中键是类,值是适当类的对象。

喜欢:

mapOf<KClass<T>, T>(
Int::class to 10,
String::class to "Ten"
)

我想使用泛型来避免“无效”条目,例如 Int::class 为“Ten”

我该如何实现它?

最佳答案

我不太确定我是否得到了您真正想要完成的任务。不要忘记泛型在运行时被删除,所以最后你只会有一个 Map<KClass<*>, Any> (更正确的是: Map<Any, Any> )。尽管如此,最简单的方法可能就是坚持您已经知道的内容。您已经展示了一种便捷方法( to )来创建 Pair然后传递给mapOf ,那么为什么不直接使用符合您要求的新函数,例如

inline fun <reified T : Any> typedPair(value : T) = Pair(T::class, value)

所以你可以使用:

mapOf(
typedPair(10), // adds Int::class as key with 10 as value
typedPair<Short>(1) // adds Short::class as key with 1 as value
typedPair<Number>(2) // adds Number::class as key with 2 as value
)

当然,这样您仍然可以将任何其他星座添加到该 map 中。如果您想克服这个问题,您还有一些不同的选择:

创建一个额外的typedMapOf怎么样?函数,例如:

fun typedMapOf(vararg values : Any) = values.associateBy { it::class }

使用它可能如下所示:

typedMapOf(10, "string", 1.toShort())

但是,您可能很难添加 Number::class然后;-)

您还可以将上面的两种变体混合起来,例如:

data class MyTypedPair<T : Any>(val type : KClass<T>, val value : T)
inline fun <reified T : Any> typedPair(value : T) = MyTypedPair(T::class, value)
fun typedMapOf(vararg values : MyTypedPair<*>) = values.associateBy({it.type}) { it.value }

现在基本上迫使您提供专门的类型来创建该类型的 map 。

我还有一些其他变体...您还可以拥有类似包装器之类的东西,只支持最少的功能集:

class MyValues {
private val backedMap = mutableMapOf<KClass<*>, Any>()
fun <T : Any> put(value : T) = backedMap.put(value::class, value)
operator fun <T : Any> get(key : KClass<T>) = backedMap[key]
}

用法与 Map 略有不同但仍然很容易:

MyValues().apply {
put(10)
put<Short>(1)
}

如果类型无法从值派生,那么您仍然可以使用上面的内容来构建可能适合您需求的解决方案。

关于generics - 如何在 Kotlin 中使用泛型创建映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55838641/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com