如果用作表达式,'if' 必须同时具有主分支和 'else' 分支

问题描述 投票:0回答:4

我之前有下面的代码工作,现在编译器停止并标记两个

if
语句并说:

如果用作表达式,'if' 必须同时具有主分支和 'else' 分支

但是正如您所看到的,这不是一个表达式,而只是一个简单的等式语句和旁边的条件语句。

try {
    val json_string = responseBody!!.string()
    val jsonObject = JSONObject(json_string)
    if (jsonObject.has("version")) {

        val remoteVersion = jsonObject.getInt("version")
        if (remoteVersion > BuildConfig.VERSION_CODE) {
            handler.post {
                showInstallNewVersionDialog()
            }
        }
    }
} catch (e: Exception) {
    e.message?.let { Log.e(Constants.TAG, e.message!!) }

}

有趣的是,如果我添加空的

else
标签,它将运行,但会警告删除空的
else
语句:

if (jsonObject.has("version")) {

    val remoteVersion = jsonObject.getInt("version")
    if (remoteVersion > BuildConfig.VERSION_CODE) {
        handler.post {
            showInstallNewVersionDialog()
        }
    } else {}
} else {}
android if-statement kotlin conditional-statements
4个回答
10
投票

如果 IDE 告诉您

'if' must have both main and 'else' branches if used as an expression
,那么就是这样。这种 try-catch 构造很可能被定义为变量的自定义 getter 或单表达式函数

一个例子:

val aVariable =
    try {
        if (System.currentTimeMillis() == 0L) {
            println("It is 1970-01-01")
        }
    } catch (e: Exception) {
        // empty
    }

fun aFunction() =
    try {
        if (System.currentTimeMillis() == 0L) {
            println("It is 1970-01-01")
        }
    } catch (e: Exception) {
        // empty
    }

IDE (lint) 在编译之前就显示错误。该函数出现同样的错误。

Error message

要解决此问题,您可以引入 else 语句或将此变量重新声明为函数(或更新您拥有的函数)。这个函数可以正常工作,因为它总是返回

Unit
,即使你没有任何代码。

fun aFunction() {
    try {
        if (System.currentTimeMillis() == 0L) {
            println("It is 1970-01-01")
        }
    } catch (e: Exception) {
        // empty
    }
}

当您使用单表达式函数或 getter 时,您必须返回一个值。这就是为什么需要

else
部分。


10
投票

问题在于 Kotlin 将

try {} catch {}
构造视为返回值的“函数”,这与 Java
try {} catch {}
不同。 因此,编译器假设您“忘记”对
else
分支进行编码,即使您显然不想返回任何值。 Kotlin 有时很可笑。

即你可以写:

val t = try {
  "test"
} catch (e: Exception) {
  "error"
}
println(t)

2
投票

如上所述,“Kotlin 有时很可笑”。 就我而言,我试图在 catch 语句中做一些事情:

fun x() {
  try {
    doSomething()
    doSomethingIfNoException()
  } catch (e:Exception) {
     if(c) doSomethingForException()
     else ""
  }
}

Kotlin 坚持 catch 中的 else。 添加 else"" 是我能找到的最简单的解决方法。


0
投票

所有答案都没有真正解释问题。这里真正的问题是异常代码

} catch (e: Exception) {
    e.message?.let { Log.e(Constants.TAG, e.message!!) }
}

整个表达式的计算结果为返回

Boolean?
。为什么?当
e.message
为 null 时,它返回 null(不是 Unit)。否则它会从
Log.e()
返回布尔值,因为 Log.e() 返回布尔值。 Kotlin 将任何计算结果为 Unit 以外的值的最终表达式视为返回表达式。这意味着整个函数都有一个隐含的布尔值?返回值。

有多种方法可以解决这个问题。在日志表达式之后调用

return
是最简单的修复方法。这明确告诉编译器不应返回任何内容。

我经常被这个问题困扰,因为日志记录函数返回一个布尔值。

© www.soinside.com 2019 - 2024. All rights reserved.