Kotlin使用getter作为只读变量

时间:2018-12-24 06:57:59

标签: android kotlin mockito robolectric

我们有什么理由要对val变量使用get()吗?

我认为以下代码不是必需的

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

所以我将其更改为

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

使用get()作为只读变量有什么区别?

3 个答案:

答案 0 :(得分:1)

您正在使用两种不同的方式来声明属性:

具有后备字段的属性

如果您声明属性context并像这样分配它:

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

您创建了一个property with backing field

实例化该类时,对

ApplicationProvider.getApplicationContext<Context>()进行一次评估。由于每次返回相同值(由函数调用分配)时,context是不可变的(val)。

没有后备字段的属性

如果您这样声明context

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

您创建了一个没有后备字段的属性。每次您访问ApplicationProvider.getApplicationContext<Context>()时都会对context进行评估。 getter返回的值可以更改,具体取决于函数的转发调用是否返回不同的内容。

使用什么?

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

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

答案 1 :(得分:0)

对于getter,无需定义get(),但需要使用setter大小写集。

从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

答案 2 :(得分:0)

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

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