HomeAndroidPerceive "by" Delegated Properties in Kotlin

Perceive “by” Delegated Properties in Kotlin


Once I first discovered Kotlin, the by operator is an alien to me. What the hell is that? On this article, I will present a easy instance to indicate the the explanation why we need to use this by operator.

Customized Property get() and set()

As an instance I need to create a customized property get() and set() to print out one thing when the property worth is learn and set. I’ll do one thing like this.

class PropertyAccessExample {  
    var worth: String? = null  
        get() {  
            println("property get worth: $area")  
            return area  
        }  
        set(worth: String?) {  
            println("property set worth from $area to $worth")  
            area = worth  
        }  

    var anotherValue: String? = null  
        get() {  
            println("property get worth: $area")  
            return area  
        }  
        set(worth: String?) {  
            println("property set worth from $area to $worth")  
            area = worth  
        }  
}

enjoyable most important() {
    val example1 = PropertyAccessExample()
    
    example1.worth = "example1"
    
    println(example1.worth)
}

Output:

property set worth from null to example1
property get worth: example1
example1

Please observe that the area right here is an implicit area. To be taught extra about Properties and Fields in Kotlin, confer with this text.

The issue of that is I must implement this practice get() and set() for all of the properties that I want to monitor. For instance, anotherValue above is the boilerplate code. To cut back the boilerplate code, we use by operator – delegated properties.

“by” Delegated Properties

To implement the by operator, we have to implement the delegated class that has applied getValue() and setValue() operator.

class PropertyDelegate<T>(non-public var worth: T? = null) {  

    operator enjoyable getValue(thisRef: Any?, property: KProperty<*>): T? {  
        println("property get worth: $worth")  
        return worth  
  }  

    operator enjoyable setValue(thisRef: Any?, property: KProperty<*>, worth: T?) {  
        println("property set worth from ${this.worth} to $worth")  
        this.worth = worth  
    }  
}

class PropertyDelegateExample {  
    var worth: String? by PropertyDelegate()  
    var anotherValue: String? by PropertyDelegate()  
}

enjoyable most important() {    
    val example2 = PropertyDelegateExample()  
    
    example2.worth = "example2"  
    
    println(example2.worth)  
}

Output:

property set worth from null to example2
property get worth: example2
example2

This line – var worth: String? by PropertyDelegate() principally means, “the property worth is offered by PropertyDelegate() delegated class. PropertyDelegate() takes duty to set and get the worth property.

Please additionally observe that the anotherValue boilerplate code is now eliminated!

Frequent Usages of “by” Operator

by lazy

The most typical utilization of delegated property in my view is by lazy. I personally desire val over var. So I exploit by lazy quite a bit every time is feasible as an alternative of utilizing lateinit var

non-public val navController: NavController by lazy {
    findNavController()
}

lazy is a delegated property that’s accountable to set the navController. lazy takes in lambda operate and that final line is the return worth of NavController. As soon as navController is accessed, the worth will likely be cached and findNavContorller() will not be known as once more within the subsequence accesses.

by viewModels

by viewModelscan be one other quite common utilization of delegated property used to create the ViewModel.

non-public val viewModel by viewModels<MainViewModel> {
    MainViewModelFactory(utility)
}

by viewModels is just like, by lazy which is restricted for ViewModel creation. It takes in lambda operate and the final line is the return worth of the implementation of ViewModelProvider.Manufacturing unit interface. For extra detailed usages, you possibly can confer with my earlier article right here.

by mutableStateOf

by mutableStateOf is what I discovered lately whereas engaged on Jetpack Compose challenge.

Methodology 1 – MutableState<T> (backing property)

In ViewModel class, as an alternative of utilizing MutableState<T> immediately,

non-public val _snackBarStringIdState: MutableState<Int?> =  mutableStateOf(null)  
val snackBarStringId  
  get() = _snackBarStringIdState.worth


_snackBarStringIdState.worth = R.string.no_internet

we will use by mutableStateOf

Methodology 2 – by mutableStateOf (non-public set)

var snackBarStringId: Int? by mutableStateOf(null)  
    non-public set


snackBarStringId = R.string.no_internet

Each strategies are comparable. The one distinction is setting the worth, as you possibly can code see within the instance above.

Conclusion

There are different delegated properties similar to observable and storing properties, and you’ll see the instance right here. Since I seldom use 2 of them, I don’t point out them right here. I’ll replace the “Frequent Usages” part above after I discover them helpful in the future.

There are additionally class delegation utilizing by operator to delegate your class implementation to a different object.

To see extra information about it, learn the next article:

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments