在写Java时分咱们对字段命名一般会用m
前缀,那么咱们在写kotlin时分却没有用这种方式呢?由于kotlin中函数是一等公民,而且能够界说顶层特点和函数,官方也就不再引荐这样的命名规范。并且更多时分称号kotlin中的变量界说为特点(properties
),而不必java中的字段(field
)。而kotlin运用”_”作为特点的前缀被称之为后备特点,先解读下官方文档进行学习。
后背字段 Backing fields
Kotlin的类不能有字段。 可是,有时在运用自界说拜访器时需要有一个后备字段。 为了这些目的,Kotlin供给了能够运用字段标识符拜访的自动备份字段:
var counter = 0 // the initializer value is written directly to the backing field
set(value) { if (value >= 0) field = value }
这里field
标识符只能在特点的set{} get{}
中拜访。在自界说拜访器经过field
标识符引用它,则将为特点生成后备字段。
在以下情况下,将不会有后备字段:
val isEmpty: Boolean
get() = this.size == 0
后备特点 Backing properties
Kotlin后备特点,下面是官方给的示例。
private var _table: Map<String, Int>? = null
val table: Map<String, Int>
get() {
if (_table == null) {
_table = HashMap() // Type parameters are inferred
}
return _table ?: throw AssertionError("Set to null by another thread")
}
咱们常常会在一些代码中看见这样的写法,很多人会表示疑问,同一个特点为何要用2个变量来持有。一般这些代码有如下特点:
- 私有的特点有
更多
可操作的性 - 对外露出的特点有
更少
的可操作性
示例1:
class TestFragment: Fragment() {
private var _binding: VB? = null
protected val binding: VB
get() = requireNotNull(_binding) { "The property of binding has been destroyed." }
...
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
示例2:
class EffectViewModel: ViewModel() {
private val _effect = MutableSharedFlow<Effect>()
val effect: SharedFlow<Effect> by lazy { _effect.asSharedFlow() }
}
示例3:
class LiveDataViewModel: ViewModel() {
private val _liveData = MutableLiveData<Int>()
val liveData: LiveData<Int> = _liveData
}
后备特点能够更好的构建安全的数据流,由于缩紧了对数据的可操作权限,对外部只供给可读取的权限。这样能够确保数据的安全性,在UDF的数据流中愈加简单定位问题和进行数据追寻。