【问题标题】:Why kotlin provide null safety operator but not exception safety operator?为什么 kotlin 提供空安全运算符而不提供异常安全运算符?
【发布时间】:2020-03-09 15:37:32
【问题描述】:

如果 kotlin 推广 安全 代码,例如:

val currentName = "Some Guy"
getDataFromServer()?.getUsers()?.find { it.name == currentName }?.profilePicture?.let {
  showPicture(it)
} ?: let {
  showAddPictureButton()
}

为什么没有类似的异常处理语法,例如使用虚构的??. 运算符:

val someUserId = 123
val newName = "Cool Dude"
connectToDatabase()??.getDao<UserDao>()??.changeUserName(someUserId, newName)??.let { newUserData ->
  reloadView(newUserData)
} ??: let { error ->
  interpretAndHandleError(error)
}

我没有看到这里的缺点。这不是语言的一部分有什么原因吗?

【问题讨论】:

  • 与 Java 不同,try/catch 是 Kotlin 中的表达式。除此之外,这个提议的语法会给我们带来什么?当某些东西可能为空引发异常时,会发生什么令人困惑。
  • 至于表达,if else也一样。我们可以写if ( someVal != null ) { someVar.property } else { null },但写someVal?.property 更健康。关于可空返回类型,是的,这是一个问题。也许仅限于非空类型?或者,如果表达式是可空类型,??. 运算符仍然可能导致可空类型,并且可以使用更强大的运算符来处理这个问题(???. 运算符?不过这是很多问号)
  • ??. 究竟会在这里返回什么?异常可以或多或少是任何类,并且可能需要自定义处理,而对于 null,您有一个“单一”案例/值,并且当您遇到 null 时,您不会做任何事情。
  • @al3c 它仍然会返回与原始表达式相同的类型。对于可空性和错误处理,必须有单独的流程。这意味着??. 运算符不会在异常时返回null,而是启动错误流,这可以由??: 运算符解决(或必须解决)。
  • 您似乎正在尝试将异常与值一起“隐藏”,这似乎很令人惊讶,您可以拥有任何类型的变量实际上隐藏异常。顺便说一句,kotlin 有 runCatchingResult 可以用来做你建议的事情,但是以一种类型安全的方式。

标签: kotlin language-lawyer kotlin-null-safety exception-safety


【解决方案1】:

这不是关于缺点,而是关于没有足够的好处。考虑在没有?. 的情况下编写您的第一个示例:

val data = getDataFromServer()
if (data != null) {
    val users = data.getUsers()
    if (users != null) {
        val user = users.find { it.name == currentName }
        if (user != null) ...
    } else null
} else null

您可以看到它比原始代码复杂得多。现在考虑在没有它的情况下编写您建议的??.

try {
    connectToDatabase().getDao<UserDao>().changeUserName(someUserId, newName).let { newUserData ->
        reloadView(newUserData)
    }
} catch(error: Exception) { 
    interpretAndHandleError(error)
}

您要消除的复杂性在哪里?

【讨论】:

    猜你喜欢
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    相关资源
    最近更新 更多