Making use of Kotlin context receivers | by Yves Kalume | Jan, 2023 | Buff Tech

roughly Making use of Kotlin context receivers | by Yves Kalume | Jan, 2023 will cowl the most recent and most present suggestion approaching the world. open slowly suitably you perceive competently and accurately. will addition your information proficiently and reliably

Typically in our code we need to use one thing solely in a sure scope, with out which it will not work accurately.

We are able to use context receivers to specific constraints.

This text goals to exhibit one of many many use circumstances and issues that Kotlin’s context receivers have been recognized to resolve through the use of an actual life case.

Let’s take an instance from Jetpack Compose. We have now modifiers that may solely be accessed inside a sure scope, equivalent to a kind of Modifier.align(alignment: Alignment) that may solely be used inside a BoxScopethe Modifier.align(alignment: Alignment.Horizontal) for ColumnScope,and so forth.

In Kotlin, you’ll be able to outline a restricted context declaration utilizing a member extension perform

interface BoxScope 
enjoyable Modifier.align(alignment: Alignment): Modifier

This modifier might be accessible solely within the context of BoxScope. To attain that, compose utilizing Field BoxScope as a recipient of your content material, and might be carried out as:

inside object BoxScopeImpl : BoxScope 
override enjoyable Modifier.align(alignment: Alignment): Modifier
/*...*/

@Composable
enjoyable Field(
modifier: Modifier = Modifier,
content material: @Composable BoxScope.() -> Unit
)
val measurePolicy = rememberBoxMeasurePolicy(contentAlignment, propagateMinConstraints)
Structure(
content material = BoxScopeImpl.content material() ,
measurePolicy = measurePolicy,
modifier = modifier
)

The contents of the field could have entry to BoxScope meaning you need to use this Modifier.align().

Disclaimer: within the code above i simply tried to simplify the compose field implementation, the purpose was to not redo it precisely however to indicate you one of many issues that context receivers come to resolve

Our drawback considerations the way in which the modifier is said.

interface BoxScope 
enjoyable Modifier.align(alignment: Alignment): Modifier
  • The secret’s {that a} member extension can’t be declared in a third celebration class. So the one solution to write one other BoxScope modifier is to put in writing it as a member of BoxScope (meaning it is unattainable)
  • Limits the power to decouple, modularize, and construction APIs into bigger functions. The modifiers should not have to be declared right here, as a result of we will create a file containing the definition of all of them.
  • One other limitation is that just one receiver can signify a context. It limits the composition of a number of abstractions, since we can’t declare a perform that ought to be known as solely inside two or extra scopes current on the similar time.
  • And many others

Context listeners are literally experimental and usually are not enabled by default. To allow its use, we have now to go to the construct.gradle.kts both construct.gradle file of our module and add -xcontext-receivers as a free compiler arg.

In it construct.gradle file from an Android module, it seems to be like this:

android 
...
kotlinOptions
jvmTarget = '1.8'
freeCompilerArgs = ["-Xcontext-receivers"]

...

Let’s return to our instance of Modifier.align() and attempt to introduce context receivers

object BoxScope 

context(BoxScope)
enjoyable Modifier.align(alignment: Alignment): Modifier
/*...*/

As an alternative of declaring our Modifier as a member extension perform, we declare it as a top-level perform and specify the scope by which it ought to be used.

Now that BoxScope would not include something, so there is not any level in implementing it, I desire to declare it straight as a object

Our checkout stays virtually the identical, besides we name straight BoxScope.content material()

@Composable
enjoyable Field(
modifier: Modifier = Modifier,
content material: @Composable BoxScope.() -> Unit
)
val measurePolicy = rememberBoxMeasurePolicy(contentAlignment, propagateMinConstraints)
Structure(
content material = BoxScope.content material() ,
measurePolicy = measurePolicy,
modifier = modifier
)

With that, we will, for instance, have one other scope that behaves like BoxScope, we cannot need to duplicate the code, we’ll simply need to cross this scope as receiver, we will actually have a modifier for ColumnScope

context(BoxScope,AnOtherLikeBoxScope)
enjoyable Modifier.align(alignment: Alignment): Modifier
/*...*/

context(ColumnScope)
enjoyable Modifier.align(alignment: Alignment): Modifier
/*...*/

Context Receivers cowl varied use circumstances, there are a number of articles that present conditions with fundamental examples that can assist you perceive this idea and its use circumstances. Personally, I used to be questioning what can be the appliance of context receivers in one of many codes that I’ve already written or seen, and this text is meant to assist all those that could also be in my place.

I want the article roughly Making use of Kotlin context receivers | by Yves Kalume | Jan, 2023 provides perception to you and is beneficial for additional to your information

Applying Kotlin context receivers | by Yves Kalume | Jan, 2023