我查看了Kotlin网站上的the docs,只有两个控制流表达式:if
和when
。
if
:表达式需要
else
分支
when
:如果不满足其他任何分支条件,则评估
else
分支。如果when
用作表达式,则else
分支是必需的,除非编译器能够证明所有可能的情况都包含在分支条件中。
所以似乎没有办法在不覆盖所有分支的情况下制作控制流表达式,是不是?如果没有,有没有办法让Control-Flow表达式错过一些分支;如果是这样,为什么?
以下代码将出现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())
}
}
}
但是下面的代码传递编译.....
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())
}
}
}
答案 0 :(得分:3)
这里的诀窍是不要将if
用作表达式。我的猜测是你将if
放在let
块上,它返回它的最后一个语句,因此使用"结果" if
的{{1}},因此将其视为表达式。
我建议丢掉let
函数(无论如何这都没用):
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())
}
}
}
您的第二个版本会进行编译,因为context!!.unregisterReceiver(this)
的类型与mListener.get()?.loggedOut(LoggedOutUserInfo())
不同,这会导致类型不匹配并阻止使用if
作为表达式。
Kotlin拥有相当多的强大控制结构。我个人更喜欢这个版本:
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())
}
}
答案 1 :(得分:1)
所以似乎没有办法制作一个Control-Flow表达式 没有覆盖所有分支,是不是?
是
在第二种情况下
mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
context!!.unregisterReceiver(this)
不再是表达式,整个if
块是一个语句。
但是,如果您确实需要表达式,还可以在第一种情况下向else
提供Unit
:
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())
} else Unit
但最好避免使用此代码,因为它的可读性较低。