首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我们必须覆盖所有分支的控制流表达式在科特林?

我们必须覆盖所有分支的控制流表达式在科特林?
EN

Stack Overflow用户
提问于 2016-11-28 08:01:15
回答 2查看 4.7K关注 0票数 6

我查看了Kotlin网站上的医生们,只有两个控制流表达式:ifwhen

对于if

表达式需要有一个else分支

对于when

如果不满足其他分支条件,则对else分支进行评估。如果使用when作为表达式,则else分支是强制性的,除非编译器能够证明所有可能的情况都包含分支条件。

问题

所以似乎没有办法在不覆盖所有分支的情况下生成一个控制流表达式,对吗?如果没有,是否有任何方法可以使Control-Flow表达式丢失某些分支;如果有,原因是什么?

下面的代码将发生if must have both main and 'else' branches if used as an expression

代码语言:javascript
复制
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())
        }
    }
}

但是下面的代码通过编译……

代码语言:javascript
复制
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())
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-28 09:01:53

这里的诀窍是不要使用if作为表达式。我的猜测是,您将if放在一个let块上,该块返回其最后一条语句,从而使用if的“结果”,从而将其视为表达式。

我建议扔掉let函数(无论如何,在这里它是无用的):

代码语言:javascript
复制
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用作表达式。

附注:

科特林有很多强大的控制结构。我个人更喜欢这个版本:

代码语言:javascript
复制
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())
    }
}
票数 12
EN

Stack Overflow用户

发布于 2016-11-28 08:59:09

所以似乎没有办法在不覆盖所有分支的情况下生成一个控制流表达式,对吗?

在第二个案例中

代码语言:javascript
复制
mListener.get()?.loggedOn(LoggedOnUserInfo.IT)
context!!.unregisterReceiver(this)

不再是表达式了,整个if块是一个语句。但是,如果确实需要表达式,也可以在第一种情况下为else提供Unit

代码语言:javascript
复制
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

但是最好避免使用这段代码,因为它的可读性较低。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40839544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档