Kotlin:编译器为什么需要`const`修饰符?

7
在Kotlin中有以下内容:
  • val - 只读属性
  • const val - 编译时常量
文档中可以看到:

编译时常量

值在编译期间已知的属性可以使用const修饰符标记为编译时常量。这样的属性需要满足以下要求:

  • 顶层或对象成员
  • 使用String类型或原始类型的值进行初始化
  • 没有自定义getter
考虑到Kotlin编译器可以识别初始化值(例如,无需在初始化程序中定义变量类型):
  • 为什么编译器需要程序员的帮助?
  • 它不能识别“在编译时已知值的属性”并自动添加const修饰符吗?
3个回答

11

const修饰符会严重改变属性的约定。

例如,如果你有一个普通属性,你可以添加一个特殊的getter而不影响使用它的代码。

然而,如果你要移除const并添加getter,则必须重新编译用户代码。换句话说,你失去了属性相对于字段的优势。


10x。我认为有必要明确指出:不允许为const val属性定义getter。 - Lior Bar-On

3
这样的关键字在两个方面都很有用:
  • 它们使编译器能够做出更强的假设,从而实现 A) 各种优化技术 B) 更严格的检查。如果你声明某个变量为const,当你试图改变它时编译器会警告你。
  • 它们表达了意图。请记住,你写代码不是为了让编译器高兴——而是为了让后来阅读这段代码的其他人理解。
意思是:如果你今天没有在源代码中加上const,但你也没有修改那个字段的语句……这是否意味着你打算让那个值成为一个常数?如果别人在某个地方添加重新分配该字段的代码,你是否介意?使用const可以明确表示你不希望发生这种情况。

3
如果你将某个变量声明为const,当你试图修改它时,编译器会警告你。但是val不是已经具有这个特性了吗? - Lior Bar-On

3
我发现Christophe Beyls的文章有助于理解使用const的"编译时优化"。
公共const vals被转换为直接访问的值。公共vals被转换为私有字节码值,并生成合成getter。
您可以通过在Intellij或Android Studio中打开Kotlin字节码查看器,为一些测试值创建一个object,并查看为valconst val生成的合成方法来尝试它。
我正在使用定义了约200个常量的对象,并且当它们都标记为const val时,生成的文件要小得多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接