我查看了Kotlin网站上的医生们,只有两个控制流表达式: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())
}
}
}发布于 2016-11-28 09:01:53
这里的诀窍是不要使用if作为表达式。我的猜测是,您将if放在一个let块上,该块返回其最后一条语句,从而使用if的“结果”,从而将其视为表达式。
我建议扔掉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用作表达式。
附注:
科特林有很多强大的控制结构。我个人更喜欢这个版本:
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())
}
}发布于 2016-11-28 08:59:09
所以似乎没有办法在不覆盖所有分支的情况下生成一个控制流表达式,对吗?
是
在第二个案例中
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但是最好避免使用这段代码,因为它的可读性较低。
https://stackoverflow.com/questions/40839544
复制相似问题