如何从枚举在 Kotlin 中创建编译时常量?
Posted
技术标签:
【中文标题】如何从枚举在 Kotlin 中创建编译时常量?【英文标题】:How to create compile-time constant in Kotlin from enum? 【发布时间】:2020-05-06 16:32:30 【问题描述】:我有一个注释,要求 defaultValue
是编译时常量。我从下面的enum
中取defaultValue
:
enum class RaceType
MARATHON,
SPRINT;
companion object
fun apply(type: RaceType): RaceDto
return when (type)
MARATHON -> MarathonDto()
SPRINT -> SprintDto()
我的dto
s 如下:
interface RaceDto
data class MarathonDto: RaceDto
data class SprintDto: RaceDto
当我使用注解 @QraphQLArgument(defaultValue = RaceType.SPRINT.name)
时,Kotlin 要求 RaceType.SPRINT.name
是编译时常量。
注解实现本身:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface GraphQLArgument
String NONE = "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
String NULL = "\n\t\t\n\t\t\n\ue000\ue001\ue002\ue003\n\t\t\t\t\n";
String name();
String description() default "";
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
Class<? extends DefaultValueProvider> defaultValueProvider() default JsonDefaultValueProvider.class;
我查看了similar questions,但没有找到解决方法。我还发现了与该主题相关的article,但到目前为止没有任何效果。
旁注:我无法更改注释,因为它来自库,我也无法更改库。
总而言之,有没有办法让 Kotlin 中的 enum
编译时常量在注解中使用?
【问题讨论】:
【参考方案1】:有没有办法让 Kotlin 中的
enum
编译时常量在注解中使用?
不,因为正式的 enum
s aren't compile-time constants in Java。
但是请考虑sealed
类:
sealed class RaceType
object MARATHON: RaceType()
const val name = "MARATHON" // copy-paste is required here until https://youtrack.jetbrains.com/issue/KT-16304
object SPRINT: RaceType()
companion object
fun apply(type: RaceType): RaceDto
return when (type) // the check is in compile time, because of sealed class
MARATHON -> MarathonDto()
SPRINT -> SprintDto()
仍然需要一小部分复制粘贴。请投票kotlin compiler bug 或follow this thread。
但是,据我了解,不幸的是,这并不能解决您对@QraphQLArgument(defaultValue = RaceType.SPRINT.name)
的问题,因为类的名称与值不同。换句话说,对于密封类,您需要编写代码将输入字符串转换为它们。
【讨论】:
谢谢。这是一个很好的解决方法,至少我知道为什么我找不到解决方案。以上是关于如何从枚举在 Kotlin 中创建编译时常量?的主要内容,如果未能解决你的问题,请参考以下文章
KotlinKotlin 变量与常量 ( 变量声明 | 只读变量 | 类型推断 | 编译时常量 | Kotlin 字节码查看面板 | Kotlin 引用数据类型 )