代码之家  ›  专栏  ›  技术社区  ›  xetra11

如何在Kotlin中为枚举值<T>创建泛型函数?

  •  0
  • xetra11  · 技术社区  · 4 年前

    我很难为使用 enumValues<MyEnum>() 功能。 让它工作 reified 但使用 inline 一路的功能对我来说是没有选择的。

        fun <T: Enum<Trait>> traits(
            selectionState: SnapshotStateMap<Trait, Boolean>
        ) {
            val chunks = enumValues<T>().toList().chunked(5)
            chunks.forEach {
                Row {
                    it.forEach {
                        TraitIcon(it, selectionState)
                    }
                }
            }
        }
    

    我的枚举都来自 enum class Trait 所以事实上我想通过 enum class TraitFoo: Trait , enum class TraitBar: Trait 以此类推。

    不能将“T”用作具体化的类型参数。使用类代替。

    这是我在这里收到的编译错误。有什么办法解决这个问题吗?我有点困惑,为什么这行不通。

    审视《公约》的实施情况 enumValues :

    public inline fun <reified T : Enum<T>> enumValues(): Array<T>
    

    我看到它使用 具体化 这确实意味着在编译时必须知道类型。因此,我不能传递泛型,但需要传递显式类型?这就是问题所在吗?

    如果是,除了使用 具体化 ?

    0 回复  |  直到 4 年前
        1
  •  1
  •   Slaw    4 年前

    如果你想使用 T 在你的函数中,如果它是一个真正的类型,那么它必须被具体化。为了使类型参数具体化,它必须是内联函数的一部分。所以你需要一个内联函数。

    下一步是弄清楚泛型。您目前拥有:

    <T : Enum<Trait>>
    

    这意味着,由于枚举的性质 T 不可能是别的 Trait 然而,你已经澄清了 特质 一个枚举,但实际上是一个接口 已实施 通过各种枚举类。所以你真正想要的是 T 受到两者的约束 Enum<T> 特质 .

    考虑到这一切,我相信你正在寻找的是以下内容:

    inline fun <reified T> traits(
        selectionState: SnapshotTraitMap<Trait, Boolean>
    ) where T : Enum<T>, T : Trait {
        val chunks = enumValues<T>().toList().chunked(5)
        chunks.forEach {
            Row {
                it.forEach {
                    TraitIcon(it, selectionState)
                }
            }
        }
    }