Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide modern and performant replacement for Enum.values() #283

Open
qwwdfsad opened this issue Dec 13, 2021 · 6 comments
Open

Provide modern and performant replacement for Enum.values() #283

qwwdfsad opened this issue Dec 13, 2021 · 6 comments

Comments

@qwwdfsad
Copy link
Contributor

qwwdfsad commented Dec 13, 2021

This proposal describes a rationale and a path to migrate from function values() provided by each enum type to a collection-based and more predictable abstraction.

Text: https://github.com/Kotlin/KEEP/pull/284/files

qwwdfsad added a commit that referenced this issue Dec 13, 2021
@Miha-x64
Copy link

Nice!
Why do you propose EnumEntriesList(Supplier) indirection? It's simpler to create a two-in-one implementation of Collections.unmodifiableList(Arrays.asList()) and pass values array directly to its constructor.

@qwwdfsad
Copy link
Contributor Author

qwwdfsad commented Jul 13, 2022

The separate type is useful for potential future additions on a standard library level instead of a language one. E.g. we can potentially extend EnumEntries to have such members as valueOfOrNull, valueOf(ignoreCase=true) and so on.

The main reason to inject supplier is to provide lazy instantiation to be compatible with enums that are being reflectively modified

@nikitabobko
Copy link
Member

E.g. we can potentially extend EnumEntries to have such members as valueOfOrNull, valueOf(ignoreCase=true) and so on.

@qwwdfsad I'm still not sure that a separate EnumEntriesList public type makes sense for this purpose. I doubt that we will ever add valueOfOrNull or valueOf(ignoreCase=true) API to EnumEntriesList. Not only it looks ugly SomeEnum.values().valueOfOrNull("Foo"), but it's also easily replaceable with List API: SomeEnum.values().firstOrNull { it.name == "Foo" }

If we will ever want to add valueOfOrNull API then unfortunately it only makes sense as a language feature: SomeEnum.valueOfOrNull("Foo")

Right now because of the EnumEntriesList API we require the OptIn which might lower the feature adoption in the preview

@ilya-g
Copy link
Member

ilya-g commented Dec 20, 2022

@nikitabobko First, it would be SomeEnum.entries.valueOfOrNull("Foo"). Second, it would be more efficient than linear search with firstOrNull.

@ZacSweers
Copy link
Contributor

ZacSweers commented Aug 9, 2023

It appears that a reified enumEntries() function wasn't added to the stlib but was called out as planned in the KEEP here: https://github.com/Kotlin/KEEP/blob/master/proposals/enum-entries.md#collateral-changes. Was this an accidental omission or an intentional change?

The reason I ask is that while most cases can just use Enum.entries, we have a helper function like this that isn't possible without a reified API.

/** Returns an enum entry with the specified name or `null` if no such entry was found. */
inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? {
  return enumValues<T>().find { it.name == name.uppercase(Locale.ENGLISH) }
}

@nikitabobko
Copy link
Member

nikitabobko commented Aug 9, 2023

It appears that a reified enumEntries() function wasn't added to the stlib but was called out as planned in the KEEP here

It will appear in Kotlin 1.9.20. The tracking issue for this function in stdlib is: https://youtrack.jetbrains.com/issue/KT-53154

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants