Kotlin 使用 getter 作为只读变量

Kotlin using getter for read-only variable

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

我觉得下面的代码没有必要

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

所以我将其更改为

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

对只读变量使用 get() 会有什么不同?

对于 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

IntelliJ Amiya 在评论中给出的 link 包含所有必要的信息,但要特别回答你的问题:

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

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

属性 带有支持字段

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

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

您创建了一个 property with backing field

ApplicationProvider.getApplicationContext<Context>() 在实例化 class 时计算一次。由于 context 是不可变的 (val),因此每次 return 编辑相同的值(由函数调用分配)。

属性 没有支持字段

如果你这样声明context

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

您创建了一个没有支持字段的 属性。 ApplicationProvider.getApplicationContext<Context>() 将在您每次访问 context 时进行评估。 getter 编辑的值 return 可以更改,具体取决于函数的转发调用 return 是否有所不同。

用什么?

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

  1. 您不能确定 ApplicationProvider.getApplicationContext<Context>() 将始终 return 相同的值,至少文档没有明确提及
  2. 转发函数调用不会对性能产生重大影响