【问题标题】:Kotlin using getter for read-only variableKotlin 使用 getter 作为只读变量
【发布时间】:2018-12-24 06:57:58
【问题描述】:

我们对 val 变量使用 get() 有什么原因吗?

我认为下面的代码是不必要的

private val context: Context get() = ApplicationProvider.getApplicationContext<Context>()

所以我把它改成了

private val context: Context = ApplicationProvider.getApplicationContext<Context>()

将 get() 用于只读变量会有什么不同?

【问题讨论】:

标签: android kotlin mockito robolectric


【解决方案1】:

您正在处理声明属性的两种不同方式:

带有支持字段的属性

如果你声明一个属性context 并像这样分配它:

private val context: Context = ApplicationProvider.getApplicationContext<Context>()

你创建了一个property with backing field

ApplicationProvider.getApplicationContext&lt;Context&gt;() 在类被实例化时被评估一次。由于 context 是不可变的 (val) 每次返回相同的值(由函数调用分配)。

没有支持字段的属性

如果你这样声明context

private val context: Context get() = ApplicationProvider.getApplicationContext<Context>()

您创建了一个没有支持字段的属性。每次访问 context 时都会评估 ApplicationProvider.getApplicationContext&lt;Context&gt;()getter 返回的值可以根据函数的转发调用是否返回不同的值而改变。

使用什么?

因此,这取决于您的用例,但在这种特殊情况下,我建议您使用不带支持字段变体的属性,原因有两个:

  1. 你不能确定 ApplicationProvider.getApplicationContext&lt;Context&gt;() 总是返回相同的值,至少文档没有明确提到这一点
  2. 转发函数调用不会对性能产生重大影响

【讨论】:

    【解决方案2】:

    对于 getter 不需要定义 get() 但 setter case set 是必需的。

    从 Kotlin 1.1 开始,如果可以从 getter 中推断出属性类型,则可以省略:

    val isEmpty get() = this.size == 0  // has type Boolean
    

    如果您需要更改访问器的可见性或对其进行注释,但不需要更改默认实现,则可以定义访问器而不定义其主体:

    var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation
    var setterVisibility: String = "abc"
    private set // the setter is private and has the default implementation
    

    ​ 更多详情请参考Properties and Fields

    【讨论】:

    • 我认为这与问题无关(除了最后的链接)。
    【解决方案3】:

    IntelliJ Amiya 在评论中提供的链接包含所有必要的信息,但特别是要回答您的问题:

    get() = ... 每次被访问时都会调用ApplicationProvider.getApplicationContext&lt;Context&gt;();只是= ... 会调用一次并存储,然后在访问时返回存储的值。您想要哪一个或它们是否有效等效(例如,主体总是返回相同的值并且足够快)取决于上下文。

    【讨论】:

      猜你喜欢
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      相关资源
      最近更新 更多