Kotlin property prefix "_" usage

When writing Java, we usually use mprefixes when naming fields, but why don't we use this method when writing kotlin? Because functions in Kotlin are first-class citizens and can define top-level properties and functions, the official no longer recommends such a naming convention. And more often than not, variables defined in Kotlin are called attributes ( ) instead of fields ( ) propertiesin Java . fieldKotlin uses "_" as the prefix of attributes, which are called backup attributes. First, read the official documents to learn.

Backing fields

Kotlin classes cannot have fields. However, sometimes you need to have a backing field when using custom accessors. For these purposes, Kotlin provides automatic backup fields that can be accessed using field identifiers:

var counter = 0 // the initializer value is written directly to the backing field
    set(value) { if (value >= 0) field = value }

This fieldidentifier can only be accessed within the attribute set{} get{}. When a custom accessor fieldrefers to it via an identifier, a backing field is generated for the property. There will be no backing field in the following cases:

val isEmpty: Boolean 
    get() = this.size == 0

Backing propertiesBacking properties

Kotlin fallback attributes , the following is the official example.

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")
    }

We often see this kind of writing in some codes, and many people wonder why the same attribute needs to be held by two variables. Generally these codes have the following characteristics:

  • Private attributes are 更多operable
  • 更少Operability of externally exposed attributes

Example 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
    }
}

Example 2:

class EffectViewModel: ViewModel() {
    private val _effect = MutableSharedFlow<Effect>()
    val effect: SharedFlow<Effect> by lazy { _effect.asSharedFlow() }
}

Example 3:

class LiveDataViewModel: ViewModel() {
    private val _liveData = MutableLiveData<Int>()
    val liveData: LiveData<Int> = _liveData
}

Backup attributes can better build a secure data flow, because the operable permissions on the data are tightened and only read permissions are provided to the outside world. This ensures data security and makes it easier to locate problems and track data in the UDF data flow.

Guess you like

Origin blog.csdn.net/Coo123_/article/details/133393783