Kotlin: Prefer clarity over concise - Level Up Coding
source link: https://levelup.gitconnected.com/kotlin-prefers-clarity-over-concise-a5a2088536b6?gi=3c54d11ef73d
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Kotlin: Prefer clarity over concise
Picture by Element5 Digital on Unsplash
Kotlin provides us a lot of handy utilities, like takeIf
etc. It can help make code so much concise, removed temporary variable, etc.
Using Kotlin takeIf (or takeUnless)
In Kotlin’s standard functions, there’s two function i.e. takeIf and takeUnless, that at first glance, what’s so…
However, if we get too much into it, it complicates the readability of the code.
Take for example the below.
savedStateHandle.get<String>(KEY).takeIf {
!it.isNullOrEmpty()
}?.let { setValue(it) } ?: removeValue()
Doing this might feel great as it:
- eliminates if-else
- chain the code together
- eliminates the temporary variable
However the downsides of this code are:
- It would take some time for one to understand the flow of the code. It obscures the simple logic behind the code.
- If we decompile the code, it generates lots of temporary variables and logics as below.
Object var2 = this.savedStateHandle.get("Key");
boolean var3 = false;
boolean var4 = false;
String it = (String)var2;
int var6 = false;
CharSequence var7 = (CharSequence)it;
boolean var8 = false;
boolean var9 = false;
String var10000 = (String)(var7 != null && var7.length() != 0 ? var2 : null);
if (var10000 != null) {
String var10 = var10000;
var3 = false;
var4 = false;
var6 = false;
Intrinsics.checkExpressionValueIsNotNull(var10, "it");
this.setValue(var10);
} else {
this.removeValue();
}
The simplified version
Let’s get back to it’s old Java way of writing, simple IF-ELSE. It doesn’t look that elegant, but one look, everything is understood.
val savedMessage = savedStateHandle.get<String>(KEY)
if (savedMessage.isNullOrBlank()) {
removeValue()
} else {
setValue(savedMessage)
}
Besides if we decompile, it looks neat too, with only little generated variables.
String savedMessage = (String)this.savedStateHandle.get("Key");
CharSequence var3 = (CharSequence)savedMessage;
boolean var4 = false;
boolean var5 = false;
if (var3 == null || StringsKt.isBlank(var3)) {
this.removeValue();
} else {
this.setValue(savedMessage);
}
Using When
Of course, if we like, we could improve it a little with when
, shorten it by one line compare with IF-ELSE
val savedMessage = savedStateHandle.get<String>(KEY)
when {
savedMessage.isNullOrBlank() -> removeValue()
else -> setValue(savedMessage)
}
The decompiled code looks good too.
String savedMessage = (String)this.savedStateHandle.get("Key");
CharSequence var3 = (CharSequence)savedMessage;
boolean var4 = false;
boolean var5 = false;
if (var3 == null || StringsKt.isBlank(var3)) {
this.removeValue();
} else {
this.setValue(savedMessage);
}
Using run
But if one complaint we need to code the temporary variable savedMessage
, we could eliminate it using run
(or some other Scope function). Like below…
savedStateHandle.get<String?>(KEY).run {
when {
this.isNullOrBlank() -> removeValue()
else -> setValue(this)
}
}
The decompiled code is the following block. Not as nice, but it’s still better than the first one.
Object var2 = this.savedStateHandle.get("Key");
boolean var3 = false;
boolean var4 = false;
String $this$run = (String)var2;
int var6 = false;
CharSequence var7 = (CharSequence)$this$run;
boolean var8 = false;
boolean var9 = false;
if (var7 == null || StringsKt.isBlank(var7)) {
this.removeValue();
} else {
this.setValue($this$run);
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK