当前位置: 首页 > 知识库问答 >
问题:

科特林:康斯特瓦尔vs瓦尔

胡景澄
2023-03-14

我知道在Kotlin中,const val用于声明常量,val用于只读属性。然而,我想知道在以下情况下,哪一个更适合使用。

假设我有一个片段,它需要一个用于SaveInstanceStaterestoreInstanceState的键。我想知道以下两个选项中哪一个更好:

class MyFragment {
    private val MY_KEY = "my_key"
    ...
}
private const val MY_KEY = "my_key" // declared in the same file.

class MyFragment {
    ...
}

我更喜欢#选项2,因为它清楚地表明MY_KEY是一个常量,值是在编译时确定的。然而,由于它是在顶层声明的,它需要在编译后的java代码中创建一个类,即MyFragmentKt(假设文件名是MyFragment.kt)。在#选项1中,没有生成额外的类,尽管MY_KEY的值将在运行时分配,而不是恒定的,但在这个特定的情况下,它的使用方式没有区别。

因此,尽管我个人更喜欢#选项2,但我的分析让我认为#选项1即使不是更好,也不是更糟。我只是想知道其他开发者是如何看待这一点的,以及#选项2是否还有其他我没有想到的好处。谢谢

共有2个答案

胥玮
2023-03-14

这两个选项之间不仅存在语义差异。

选项1(val在类中)是一个实例字段。

选项2(顶级const val)是顶级“静态”成员(大致上,因为static在Kotlin中不存在)

这就是为什么要生成一个MyFragmentKt类:顶级成员被编译成一个名为[Filename]Kt的类。

我会考虑第三种选择:

class MyFragment {
    companion object {
        private const val MY_KEY = "my_key"
    }
}

这样,MY_KEY是(来自Java)MyFraank类的静态成员,因为JvmStatic是为const变量推断的。

由于您最初的方法是类中的一个字段,我觉得伴随对象/静态常量可能更可取。

更多关于伴生对象s与Java的静态

蒋默
2023-03-14

每次编写(非内联)lambda表达式时,都创建了另一个类。相比之下,创建一个类来保存顶级声明似乎微不足道。

此外,如果顶层只有一个常量声明,它将被内联到每个使用站点(按规范)中,因此所属类本身将不被引用,因此ProGuard的最小化可以将其作为目标。它很可能不会出现在您的生产APK中。

 类似资料:
  • 然后Android Studio告诉我,x应该用而不是来声明。 我知道和之间有什么区别。 如果我不需要给赋值,它可能是。 但是在运行时会有什么不同吗? 当我用而不是来声明变量时,会不会更快? 这不是重复的!我问的是性能,而不是意义上的差异。

  • 嗨,我运行ionic命令时出现以下错误()。任何线索都将不胜感激。我的Java是9.0.1,错误消息对我来说没有意义。请提出你的想法。 ANDROID_HOME=C:\程序文件(x86)\Android\android-sdkJAVA_HOME=C:\程序文件\Java\jdk-9.0.1错误:JDK 1.8或更高版本的需求检查失败 [错误]运行科尔多瓦运行Android时出错(退出代码 1)。

  • OS: OSX 10.11科尔多瓦: 5.4.1(也在6.0上尝试)节点: 4.2.6科尔多瓦插件使用:人行横道-项目/科尔多瓦-插件-人行横道-网络视图(1.5),phonegap/phonegap-plugin-推送(1.5.3),和dariosalvi78/科尔多瓦-插件-健康(0.5.3) 运行时,我收到以下错误 出了什么问题:执行任务失败:dexArmv7Debug。com.androi

  • 如何在使用Kotlin的Spring Boot中正确初始化ConfigurationProperties? 目前我喜欢下面的例子: 但是它看起来很丑陋,实际上不是一个iable,foo是常量ue,应该在启动期间初始化,将来不会改变。

  • 或 我很困惑为什么需要lateinit关键字,如果我们可以让var为空并在以后分配它。每种方法的利弊是什么?每种方法应该在什么情况下使用?