I looked at the docs from Kotlin website, there are only two Control-Flow expressions: if and when.
if:the expression is required to have an
elsebranch
when:The
elsebranch is evaluated if none of the other branch conditions are satisfied. Ifwhenis used as an expression, theelsebranch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions.
So it seems that there is no way to make a Control-Flow expression without covering all branches, Is it right? If not, Is there any way to make a Control-Flow expression to miss some branches; If so, why?
Following code will occur if must have both main and 'else' branches if used as an expression
override fun onReceive(context: Context?, intent: Intent?) {
intent?.let {
if (it.action == MySDK.BROADCAST_ACTION_LOGIN) {
mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
}else if (it.action == MySDK.BROADCAST_ACTION_LOGOUT) {
// Occur 'if must have both main and 'else' branches if used as an expression'
mListener.get()?.loggedOut(LoggedOutUserInfo())
}
}
}
But following code pass compile.....
override fun onReceive(context: Context?, intent: Intent?) {
intent?.let {
if (it.action == MySDK.BROADCAST_ACTION_LOGIN) {
mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
context!!.unregisterReceiver(this) // only add this line to test.
}else if (it.action == MySDK.BROADCAST_ACTION_LOGOUT) {
mListener.get()?.loggedOut(LoggedOutUserInfo())
}
}
}
The trick here is not to use the if as an expression. My guess is that you placed the if at a let block, which returns its last statement, thus using the "result" of the if, thus treating it as an expression.
I suggest throwing away the let function (it is useless anyway here):
override fun onReceive(context: Context?, intent: Intent?) {
if(intent != null) {
if (intent.action == MySDK.BROADCAST_ACTION_LOGIN) {
mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
} else if (intent.action == MySDK.BROADCAST_ACTION_LOGOUT) {
mListener.get()?.loggedOut(LoggedOutUserInfo())
}
}
}
Your second version compiles because context!!.unregisterReceiver(this) has a different type than mListener.get()?.loggedOut(LoggedOutUserInfo()), which makes the types mismatch and prevents using the if as an expression.
Kotlin has quite a few powerful control structures. I personally prefer this version:
override fun onReceive(context: Context?, intent: Intent?) {
intent ?: return
when(intent.action) {
MySDK.BROADCAST_ACTION_LOGIN -> mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
MySDK.BROADCAST_ACTION_LOGOUT -> mListener.get()?.loggedOut(LoggedOutUserInfo())
}
}
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