gpt4 book ai didi

kotlin - 为什么 Kotlin 枚举属性不是编译时常量?

转载 作者:行者123 更新时间:2023-12-05 01:54:54 27 4
gpt4 key购买 nike

这个问题的主要目标是了解实现及其原因。它的解决方案或解决方法当然也会受到高度赞赏......

给出这个例子:

enum class SomeEnum(val customProp: String) {
FOO("fooProp"),
BAR("barProp");
}

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.SOURCE)
annotation class TheAnnotation(
val targetValue: String
)

@TheAnnotation(targetValue = SomeEnum.FOO.customProp)
fun testFun() {

}

编译结果出现如下错误:

SomeEnum.kt: (14, 30): An annotation argument must be a compile-time constant

出于显而易见的原因,注释值(连同其他值)必须是编译时常量,这在许多不同方面都有意义。我不清楚的是为什么编译器不将 customProp 视为常量。

如果枚举被定义为有限的、封闭的信息集,在我看来,它们应该只在编译时可变,也就是“编译时常量”。对于枚举在 Kotlin 运行时以某种方式可以修改的不太可能的情况,这也可以回答这个问题。

附录:

枚举值(例如 SomeEnum.FOO)实际上被视为编译时常量。证明是,以下稍作更改的代码段可以编译:

enum class SomeEnum(val customProp: String) {
FOO("fooProp"),
BAR("barProp");
}

@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class TheAnnotation(
val targetValue: SomeEnum
)

@TheAnnotation(targetValue = SomeEnum.FOO)
fun testFun() {

}

最佳答案

enums are defined as finite, closed sets of information, they should, in my understanding, only be mutable at compile-time

实际上,没有。枚举类只是一种特殊的类,它不允许您创建除您在声明中命名的实例之外的任何新实例,以及更多的语法糖。因此,与常规类一样,它可以具有值仅在运行时已知的属性,以及可变的属性(尽管这通常是一个非常糟糕的主意)。

例如:

enum class Foo {
A, B;

val foo = System.currentTimeMillis() // you can't know this at compile time!
}

这基本上脱糖成:

class Foo private constructor(){
val foo = System.currentTimeMillis()
companion object {
val A = Foo()
val B = Foo()
}
}

(实际生成的代码比这个多了一点,但这足以说明我的观点)

AB 只是 Foo 的两个(而且只有两个)实例。很明显 Foo.A 不是编译时常量*,更不用说 Foo.A.foo 了。您可以在 Foo 中添加一个 init block 来运行任意代码。你甚至可以让 foo 成为 var,允许你做一些可怕的事情,比如:

Foo.A.foo = 1
// now every other code that uses Foo.A.foo will see "1" as its value

您可能还想知道为什么他们没有实现一个不允许您做这些事情的更受限制的枚举,并且一个编译时间常量,但是that is a different question .

另请参阅:The language spec


* 虽然您仍然可以将 Foo.A 传递给注释。对于注解,Foo.A 是一个编译时常量,因为所有注解必须做的是存储名称“Foo.A”,而不是它所引用的对象,它必须在运行时计算。

关于kotlin - 为什么 Kotlin 枚举属性不是编译时常量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70472541/

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