Is it a good practice to use multiple nested let
in Kotlin or should I introduce a local variable instead? Is there any overhead?
webView?.let { webview ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webview.setLayerType(View.LAYER_TYPE_HARDWARE, null)
} else {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
webview.webViewClient = WebViewClient()
webview.settings.let { settings ->
settings.javaScriptEnabled = true
settings.setSupportZoom(false)
settings.builtInZoomControls = false
settings.displayZoomControls = false
settings.loadsImagesAutomatically = true
}
}
Since let
is inlined (see: what is inlining, also the official docs), its cost is the exact same as declaring the local variable yourself. If you're using it with a safe call, it also adds a null check, which you'd have to do manually as well.
So there's basically no overhead to using it, feel free to use it as much as you want as long as your code is legible enough for you.
For example, code like this:
webview.settings.let { settings ->
settings.javaScriptEnabled = true
settings.setSupportZoom(false)
}
... would roughly translate to bytecode equivalent to this Java code:
Settings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setSupportZoom(false);
Except settings
would probably be called something generic like var10000
, but that's besides the point. Point is that no function instances are created and no let
function is called or anything like that, therefore no overhead.
For any future concerns, you can actually check this yourself by using the Kotlin plugin's bytecode viewer and decompiler.
Kotlin's creators recommend not to use too many nested let
calls to achieve better code readability and conciseness. In their book 'Kotlin in Action' they say
When you need to check multiple values for
null
, you can use nestedlet
calls to handle them. But in most cases, such code ends up fairly verbose and hard to follow. It’s generally easier to use a regularif
expression to check all the values together.
A side remark. The inner let
block could be rewritten for better readability with run
:
webview.settings.run {
javaScriptEnabled = true
setSupportZoom(false)
builtInZoomControls = false
displayZoomControls = false
loadsImagesAutomatically = true
}
As an addition to zmbs13's answer:
Since you don't need a null check for webview.settings
, it would be better to use apply which takes a lambda with receiver:
webview.settings.apply {
// you refer to webview.settings with 'this', which can be omitted
this.javaScriptEnabled = true // using this explicitely, in case there is another variable 'javaScriptEnabled' in this block
setSupportZoom(false) // omitting this from here on
builtInZoomControls = false
displayZoomControls = false
loadsImagesAutomatically = true
}
This makes your code even more concise and avoids the redundancy of having to write settings
, or it
multiple times.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With