ITmob-Ly
发布于 2023-07-14 / 160 阅读
0

为什么在 Kotlin 1.9.0 中引入entries属性来替代values()函数?

Kotlin-Blog

在 Kotlin 1.9.0 中,为枚举引入了entries属性来替代values()函数。因为 values() 函数作为返回一个包含所有枚举条目的数组的方法,存在一些问题…

介绍

values() 存在的问题:

该方法返回所有枚举条目的数组。默认情况下,数组是可变的,这意味着每次调用 values() 始终必须分配数组的新实例。这会导致隐藏的性能问题。

values() 返回 Array<E> 类型,默认情况下它是可变的,并且使用起来没有 List 灵活

更多关于 values() 的问题可参见文档:https://github.com/Kotlin/KEEP/blob/master/proposals/enum-entries.md#examples-of-performance-issues

https://youtrack.jetbrains.com/issue/KT-48872/Provide-modern-and-performant-replacement-for-Enum.values

entries 属性是在 Kotlin 1.8.20 中作为实验性功能引入的,在 Kotlin 1.9.0 中已经稳定

entries 属性返回一个预先分配的枚举常量的不可变列表(Immutable List):entries: EnumEntries<E>,它返回所有枚举条目的只读列表的缓存实例

例如:

enum class RGB { RED, GREEN, BLUE }

fun main() {
    for (color in RGB.entries) println(color.toString())
    // prints RED, GREEN, BLUE
}

扩展 entries 属性的返回值

entries 属性的返回值是 EnumEntries 类型,它是 List 的子类,所以 List 的所有函数和扩展都可使用,因此比 values() 函数返回的 Array 类型更灵活。

如下是源码中 EnumEntries 的定义:

@SinceKotlin("1.9")
@WasExperimental(ExperimentalStdlibApi::class)
public sealed interface EnumEntries<E : Enum<E>> : List<E>

我们还可以为 entries 属性的返回值自定义扩展,例如:

enum class RGB { RED, GREEN, BLUE }

fun EnumEntries<RGB>.extensionSample() {
    // TODO extension
    println(this)
}

fun main() {
    for (color in RGB.entries) println(color.toString())
    // prints RED, GREEN, BLUE
    RGB.entries.extensionSample()
    // prints [RED, GREEN, BLUE]
}