-1

我理解 Kotlin 的!!操作符是做什么的。我想知道是否有任何用例可以更好地!!代替?.letor?: return或其他更安全的空检查。

关于 null 安全性的Kotlin 文档只是说它适用于喜欢 NullPointerExceptions 的人;人们为什么要那些?

我主要只是好奇它是否有用例,没有更好的选择。

4

2 回答 2

2

不是每个人都是初学者。使用此运算符的感叹号有助于表示如果您确实使用它,您会更好地了解自己在做什么。

在某些情况下,它会产生更清晰的代码。我在使用第三方库时经常看到这种情况。

例如,Android 是LiveData.value可以为空的,但如果你在初始化它时设置正确的值,那么你就知道该值永远不会为空。

val myLiveData = MutableLiveData<Float>().apply{ value = 1f }

这是一个见仁见智的问题,但我认为使用未使用的默认值乱扔对该 getter 的每个引用会非常嘈杂:

when ((myLiveData.value ?: 1f) > 0f) { /* */ }

对比

when (myLiveData.value!! > 0f) { /* */ }

就个人而言,如果我使用课堂外的实时数据,我不会使用双键,因为这样就无法明确保证它实际上有一个值集。但是在包含它的类中,您可以相信自己知道自己在做什么。

这是来自 Android 的另一个示例。当您在 PreferenceFragmentCompat 中工作并且需要获取 Preference 引用时,findPreference如果首选项不在层次结构中,则使用返回 null。如果您知道 Preference 应该存在,那么使用它是有意义的,!!因为如果它实际上不存在,您希望看到异常。或者,您可以使用?: error("missing preference"),但它是额外的代码,并不能真正使堆栈跟踪中的问题更加明显。或者您可能很想使用findPreference("x")?.let { //... },但是当缺少首选项时它会默默地失败,如果您知道首选项应该在那里,这不是您想要的。

当然,使用时要小心!!。如果您的特定 PreferenceFragment 通过在各种情况下添加和删除它们来对 Preferences 进行一些操作,那么在测试期间使用可能更合适的是?.let {/**/} ?: Log.e(...)您错过了当您认为它会出现偏好不存在的情况时.

于 2020-02-25T19:16:27.467 回答
1

null只要值表明代码本身不正确,您就会想抛出 NullPointerException 。就像如果无效参数表明调用者的代码不正确,您可能会显式抛出 IllegalArgumentException。

因此, for 的用例与 for 的用例!!非常相似if(...) { throw ...; },但!!更短。

如果代码不正确,您了解它们,并立即使用堆栈跟踪停止程序是(1)通知程序员问题的好方法,以及(2)提供尽可能多的有用信息调试目的。

于 2020-02-25T20:44:51.267 回答