【问题标题】:Kotlin: why the compiler needs the `const` modifier?Kotlin:为什么编译器需要 `const` 修饰符?
【发布时间】:2017-08-11 06:58:33
【问题描述】:

在 Kotlin 中有:

  • val - 只读属性
  • const val - 编译时常量

来自documentation

编译时常量

可以使用const 修饰符将其值在编译时已知的属性标记为编译时常量。此类属性需要满足以下要求:

  • 对象的顶级或成员
  • 使用 String 类型或原始类型的值初始化
  • 没有自定义 getter

鉴于 kotlin 编译器确实知道识别初始化值(例如不需要在初始化程序中定义变量类型):

  • 为什么编译器需要程序员的帮助?
  • 它不能识别“在编译时知道其值的属性”并单独“添加”const 修饰符吗?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    const 修饰符严重改变了财产的合同。

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

    另一方面,您必须重新编译用户代码才能删除const 并添加getter。换句话说,您失去了拥有属性优于字段的优势。

    【讨论】:

    • 10 倍。我认为值得特别说明:不允许为const val 属性定义getter。
    【解决方案2】:

    此类关键字在两种方面有帮助:

    • 它们允许编译器做出更强的假设。这使得 A) 各种优化技术 B) 更严格的检查。如果您将某项声明为const,编译器可能会在您尝试更改它时拍打您的手指。
    • 他们表达 意图。请记住,您编写代码并不是为了让编译器满意,而是为了与稍后阅读此代码的其他人交流。

    含义:如果你今天没有在源代码中写下 const - 但你也没有声明 modifying 该字段...这是否意味着你打算该值是一个常数?您是否介意其他人添加在某个地方重新分配该字段的代码?通过使用const,您明确表示您希望这种情况发生。

    【讨论】:

    • “如果你声明某个东西是 const,当你试图改变它时,编译器会打你的手指。” - val 不是这样吗?
    【解决方案3】:

    我发现Christophe Beyls's article 有助于理解使用const 的“编译时优化”。

    公共const vals 被转换为可直接访问的值。公共vals 被转换为私有字节码值并生成合成getter。

    您可以通过在 Intellij 或 Android Studio 中打开 Kotlin 字节码查看器来亲自尝试,为一些测试值创建一个 object,并查看为 valconst val 生成的合成方法。

    我正在使用一个定义了大约 200 个常量的对象,当它们都被标记为 const val 时,会生成一个小得多的文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多